Java IO 流全介绍

  • java 流概述
  • 文件流
  • FileInputStream
  • FileOutputStream
  • FileReader
  • FileWriter
  • 缓冲流
  • BufferedInputStream
  • BufferedOutputStream
  • BufferedReader
  • BufferedWritter
  • 装饰着模式(Decorator)
  • 数据字节流
  • 打印流
  • 对象流
  • 对象序列化&反序列化
  • 序列化版本号:SerialVersion_UID
  • File 类


java 流概述

  • 流根据方向可以分为:输入流和输出流
  • 注意:输入和输出是相对于内存而言的
  • 从内存中出来就是输出,到内存中就是输入
  • 输入流 又叫做 InputStream
  • 输出流又叫做 OutputStream
  • 输入 还叫作"读",Read
  • 输出还叫作“写”, Write
  • 流根据读取数据的方式可以分为:字节流和字符流
  • 字节流是按照字节的方式读取
  • 字符流是按照字符的方式读取,一次读 2 个字节
  • java 语言中一个字符 占 2 个字节
  • 字节流适合读取:视频、声音、图片等二进制文件
  • 字符流适合读取:纯文本文件
  • Java语言中所有的字节流都以Stream结尾
  • 所有的字符流都含有Reader或者Writer

java io 对象流 java io流详解_java

  • 需要重点掌握的16个流
java.io.*;

FileInputStream
FileOutputStream
FileReader
FileWriter

BufferedInputStream
BufferedOutputStream
BufferedReader
BufferedWriter

DataInputStream
DateOutputStream

ObjectInputStream
ObjectOutputStream

转换流(字节流转换成字符流)
InputStreamReader
OutputStreamWriter

PrintWriter
PrintStream // 标准的输出流(默认输出到控制台)
  • Java语言中的流分为四大家族
  • InputStream
  • OutputStream
  • Reader
  • Writer
  • InputStreamOutputStream 继承结构图

java io 对象流 java io流详解_java io 对象流_02

  • ReaderWriter 继承结构图

文件流

FileInputStream

  • 继承结构
java.io.InputStream;
--- java.io.FileInputStream; // 文件字节输入流

按照字节方式读取文件

  • 举例1-使用read()方法 一次读取一个字节

    该方法返回的int 类型的值表示读取的字节。
import java.io.*;

public class Test01 {
	public static void main(String[] args){
		FileInputStream fis = null;
		// 1. 要读取文件,先与这个文件创建一个输入流
		// 文件路径
		String filePath = "D:\\CodeFiles\\CodeTrain\\code_train\\src\\com\\test\\inputoutput\\temp01";
		try {
			fis = new FileInputStream(filePath);
			// 2. 开始读
			// int read() // --> Reads a byte of data from this input stream.
			int i1 = fis.read();// 以字节的方式读取
			int i2 = fis.read();// 以字节的方式读取
			int i3 = fis.read();// 以字节的方式读取
			int i4 = fis.read();// 以字节的方式读取
			int i5 = fis.read();// 以字节的方式读取
			int i6 = fis.read();// 以字节的方式读取
			int i7 = fis.read();// 以字节的方式读取
			int i8 = fis.read();// 以字节的方式读取
			System.out.println(i1);// a -> 97
			System.out.println(i2);// b -> 98
			System.out.println(i3);// c -> 99
			System.out.println(i4);// d -> 100
			System.out.println(i5);// e -> 101
			System.out.println(i6);// f -> 102
			System.out.println(i7);// 结束 -> -1
			System.out.println(i8);// 结束 -> -1	
		}catch(FileNotFoundException e) {
			e.printStackTrace();
		}catch(IOException e){
			e.printStackTrace();
		}finally {
			try {
				fis.close();
			}catch(IOException e) {
				e.printStackTrace();
			}
		}	
	}
}
/*输出
97
98
99
100
101
102
-1
-1
*/
  • 测试
import java.io.*;
public class Test02 {
	public static void main(String[] args) throws Exception{
		// 1. 创建文件流
		// 文件路径
		String filePath = "D:\\CodeFiles\\CodeTrain\\code_train\\src\\com\\test\\inputoutput\\temp01";
		FileInputStream fis = new FileInputStream(filePath);
		// 2. 读
		while(true) {
			int temp = fis.read();
			if(-1 == temp) {
				break;
			}
			System.out.println(temp);
		}
        // 3. 关闭流
		fis.close();
	}
}
/*输出
97
98
99
100
101
102
*/
  • 测试
import java.io.*;

public class Test03 {
	public static void main(String[] args) throws Exception{
		// 1. 创建文件流
		// 文件路径
		String filePath = "D:\\CodeFiles\\CodeTrain\\code_train\\src\\com\\test\\inputoutput\\temp01";
		FileInputStream fis = new FileInputStream(filePath);
		// 2. 读
		int temp = 0;
		while((temp = fis.read()) != -1) {
			System.out.println(temp);
		}
        // 3. 关闭流
		fis.close();
	}
}
/*输出
97
98
99
100
101
102
*/
  • 使用read()方法读取文件数据的缺点
  • 效率较低,一次只能读取1字节
  • 频繁访问磁盘,对磁盘伤害较大
  • 举例2- 使用 read(byte[] b)读取文件,每次都读取固定长度的字节存储到字节数组中

java io 对象流 java io流详解_System_03

int read(byte[] b);
读取之前在内存中准备一个 byte 类型的数组,每次读取多个字节存储在 byte 数组中。
一次读取多个字节,不是单字节读取了,效率较高

该方法返回的int类型的值代表的是:该次读取了多少字节

  • 如果没有读取到,即已经到达了文件的末尾,则返回 -1
import java.io.*;
public class Test04 {
	public static void main(String[] args) throws Exception{
		// 1. 创建输入流
		String filePath = "D:\\CodeFiles\\CodeTrain\\code_train\\src\\com\\test\\inputoutput\\temp01";
		FileInputStream fis = new FileInputStream(filePath);
		// 2. 读
		byte[] bytes = new byte[3];// 每一次最多读取3个字节
		int i1 = fis.read(bytes); // 3
        // byte数组转换成字符串
		System.out.println(new String(bytes));//abc
		int i2 = fis.read(bytes); // 3 
		System.out.println(new String(bytes));// def
		int i3 = fis.read(bytes); // 1
		System.out.println(new String(bytes, 0, i3));// g
		int i4 = fis.read(bytes); // -1 已经到达文件末尾, 返回 -1
		// 3. 关闭
		fis.close();
	}
}
  • 测试-使用循环读取
import java.io.*;

public class Test05 {
	public static void main(String[] args) throws Exception{
		String filePath ="D:\\CodeFiles\\CodeTrain\\code_train\\src\\com\\test\\inputoutput\\temp01";
		FileInputStream fis = new FileInputStream(filePath);
		byte[] bytes = new byte[1024];// 每次最读取1024字节
		while(true) {
			int temp= fis.read(bytes);
			if(-1 == temp) {
				break;
			}
			// 讲byte中有效的数据转换成字符串
			System.out.println(new String(bytes, 0, temp));
		}
		fis.close();
	}
}
// 输出
// abcdefg
  • 测试-使用循环读取
import java.io.*;
public class test06 {
	public static void main(String[] args) throws Exception{
		String filePath = "D:\\CodeFiles\\CodeTrain\\code_train\\src\\com\\test\\inputoutput\\temp01";
		FileInputStream fis = new FileInputStream(filePath);
		int temp =0;
		byte[] bytes = new byte[1024];
		while((temp = fis.read(bytes)) != -1) {
			System.out.println(new String(bytes, 0, temp));
		}
		fis.close();
	}
}
  • 举例3-使用available()方法 返回流中剩余的估计字节数,使用 skip(long n)方法跳过 n 个字节
import java.io.*;

public class Test07 {
	public static void main(String[] args) throws Exception{
		String filePath = "D:\\CodeFiles\\CodeTrain\\code_train\\src\\com\\test\\inputoutput\\temp01";
		FileInputStream fis = new FileInputStream(filePath);
		int i1 = fis.available();
		System.out.println(i1); // 7
		int i2 = fis.read();// 读取一个字节:a-97
		int i3 = fis.available();// 剩余的估计字节数
		System.out.println(i3);// 6
		long l1 = fis.skip(2); // 返回实际跳过的字节数
		System.out.println(l1);//2
		int i4 = fis.available();//4
		System.out.println(i4);
		int i5 = fis.read();
		System.out.println(i5);// d-100
		fis.close();
	}
}

FileOutputStream

  • 继承结构
java.io.OutputStream;
---- java.io.FileOutputStream; // 文件字节输出流

将计算机内存中的数据写入硬盘文件中。

  • 构造方法
  • 举例1-使用 FileOutputStream(String name) 方法覆盖原始文件内容
import java.io.*;
public class Test08 {
	public static void main(String[] args) {
		String filePath = "temp02";
		FileOutputStream fos = null;
		try {
			// 创建文件字节输出流
			fos = new FileOutputStream(filePath);// 文件不存在则自动创建
			// 开始写数据
			String msg = "HelloWorld";
			// 字符串转换为byte数组
			byte[] bytes = msg.getBytes();
			fos.write(bytes);
			// 推荐最后的时候为了保证数据完全写入硬盘,执行刷新函数
			fos.flush();// 强制写入
		}catch(Exception e) {
			e.printStackTrace();
		}finally {
			if(fos != null) {
				try {
					fos.close();
				}catch(IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
}
  • 举例2-使用使用 FileOutputStream(String name, boolean append)方法在原来的文件后面追加数据
import java.io.*;
public class Test09 {
	public static void main(String[] args) throws Exception{
		String filePath = "temp02";
		// 创建文件字节输出流
		// 在文件末尾追加数据
		FileOutputStream fos = new FileOutputStream(filePath, true);
		String msg = "helloWorld!!";
		// 字符串转换为 bytep[]
		byte[] bytes = msg.getBytes();
		// 写
		fos.write(bytes);
		// 写一部分数据 void write(byte[] b, int off, int len)
		fos.write(bytes, 2, 3);
		fos.flush();
		fos.close();
	}
}
  • 举例3-实现文件的复制粘贴
import java.io.*;

public class Test10 {
	public static void main(String[] args) throws Exception{
		// 创建输入流
		FileInputStream fis = new FileInputStream("D:\\personalData\\music\\music163\\Aki阿杰 - 一世妆.mp3");
		// 创建输出流
		FileOutputStream fos = new FileOutputStream("test.mp3");
		// 一边读,一边写
		byte[] bytes = new byte[1024];
		int temp = 0;
		while((temp=fis.read(bytes)) != -1) {
			fos.write(bytes, 0, temp);
		}
		
		// 刷新
		fos.flush();
		// 关闭流
		fis.close();
		fos.close();
	}
}

FileReader

  • 继承结构
java.io.Reader;
	java.io.InputStreamReader;	// 转换流(字节输入流--> 字符输入流)
		java.io.FileReader;   // 文件字符输入流
  • 举例1-读取纯文本文件
import java.io.*;

public class Test11 {
	public static void main(String[] args) {
		// 创建文件字符输入流
		FileReader fr = null;
		try {
			fr = new FileReader("temp02");
			char[] ch = new char[512];
			int temp = 0;
			while((temp = fr.read(ch)) != -1) {
				System.out.println(new String(ch, 0, temp));
			}
		}catch(Exception e) {
			e.printStackTrace();
		}finally {
			if(fr != null) {
				try {
					fr.close();
				}catch(Exception e) {
					e.printStackTrace();
				}
			}
		}
	}
}

FileWriter

  • 继承结构图
java.io.Write;
	java.io.OutputStreamWriter;//转换流(字节输出流转换成字符输出流)
		java.io.FileWriter;// 文件字符输出流
  • 举例1-写文件
import java.io.*;
public class Test12 {
	public static void main(String[] args) throws Exception{
//		FileWriter fw = new FileWriter("temo03");
		FileWriter fw = new FileWriter("temo03", true);
		//写
		String str = "巴拉巴西";
		fw.write(str);
		char[] nchr = {'我','是','中'}; 
		fw.write(nchr, 0, 2);
		// 刷新
		fw.flush();
		// 关闭
		fw.close();
	}
}
  • 举例2-使用FileReaderFileWriter实现文件的复制粘贴
import java.io.*;

public class Test13 {
	public static void main(String[] args) throws Exception{
		// 创建文件字符输入流
		FileReader fr = new FileReader("temp02");
		// 创建字符输出流
		FileWriter fw = new FileWriter("temp03");
		
		int temp = 0;
		char[] ncha = new char[512];
		while((temp = fr.read(ncha))!=-1) {
			fw.write(ncha, 0, temp);
		}
		// 刷新
		fw.flush();
		// 关闭
		fr.close();
		fw.close();
	}
}

缓冲流

BufferedInputStream

不说了,参照BufferedReader

BufferedOutputStream

不说了,参照BufferedWriter

BufferedReader

  • 继承结构
java.io.Reader;
	java.io.BufferedReader;
  • 构造方法
  • Reader是一个抽象类,抽象类不能实例化,所以可以使用 FileReader文件字符输入流

java io 对象流 java io流详解_输出流_04

  • 举例1-使用带缓冲区的字符输入流读文件
import java.io.*;
public class Test14 {
	public static void main(String[] args) throws Exception{
		FileReader fr = new FileReader("temp02");//创建一个文件字符输入流
		BufferedReader br = new BufferedReader(fr);// 将文件字符输入流包装成带有缓冲区的字符输入流
		
		// 开始读
		String temp = null;
		while((temp=br.readLine())!=null) {// br.readline();方法读取一行,但是行尾不带换行符
			System.out.println(temp);// 输出一行
		}
		// 关闭
		// 注意:关闭只需要关闭最外层的包装流(这里有一个装饰者模式)
		br.close();
	}
}
  • 根据流出现的位置,可以分为:包装流或者处理流 和 节点流
  • FileReader fr是一个节点流
  • BufferedReader br是一个包装流或者处理流
  • readline() 方法读取一行时,不会读取换行符
  • 举例2-使用InputStreamReader转换流将字节输入流转换成字符输入流传入到BufferedReader()
import java.io.*;
public class Test15 {
	public static void main(String[] args) throws Exception {
		FileInputStream fis = new FileInputStream("temp02");// 文件字节输入流
		// 转换流,将字节输入流转换成字符输入流
		InputStreamReader isr = new InputStreamReader(fis);// isr是字符流
		BufferedReader br = new BufferedReader(isr);
		//br = new BufferedReader(new InputStreamReader(new FileInputStream("temp02")));
		// 开始读
		String temp = null;
		while((temp = br.readLine())!=null) {
			System.out.println(temp);
		}
		// 关闭
		// 只需要关闭最外层包装流(装饰者模式)
		br.close();
	}
}
  • 举例3-接收用户键盘输入
import java.io.*;
public class Test16 {
	public static void main(String[] args) throws Exception{
		// System.in 是一个标准字节输入流,默认接收键盘的输入
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		String str = br.readLine();
		System.out.println(str);
	}
}

BufferedWritter

  • 继承结构
java.io.Writer;
	java.io.BufferedWriter;
  • 举例1-使用带缓冲区的字符输出流实现文件写操作
import java.io.*;
public class Test17 {
	public static void main(String[] args) throws Exception{
		BufferedWriter bw = new BufferedWriter(new FileWriter("temp04", true));
		bw.write("hello world");
		bw.newLine();// 写入换行符
		bw.write("嘻嘻哈哈和");
		bw.flush();
		bw.close();
	}
}
  • 举例2- 使用BufferedReaderBufferedWriter 实现文件的拷贝
import java.io.*;
public class Test18 {
	public static void main(String[] args) throws Exception{
		BufferedReader br = new BufferedReader(new FileReader("temp04"));
		BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("temp05")));
		String temp = null;
		while((temp=br.readLine())!=null) {
			bw.write(temp);
			bw.newLine();
		}
		
		bw.flush();
		br.close();
		bw.close();
	}
}

装饰着模式(Decorator)

  • 如何实现对类中某一个方法的扩展(不改变原来的类)?
  • 继承(泛化关系,耦合度较高)
public class FileReader{
    void close(){
        System.out.println("fileReader closed!");
    }
}
public class BufferedReader extends FileReader{
    // 扩展 FileReader 里面的close() 方法
    void close(){
        System.out.println("BufferedReader closed");
        super.close();
        System.out.println("BufferedReader closed");
    }
}
public class Test{
    public static void main(String[] args){
        BufferedReader br = new BufferedReader();
        br.close();
    }
}
  • 装饰者模式(关联关系,耦合度低)
  • 装饰者模式中要求:装饰者中含有被装饰者的引用
  • 装饰者模式中要求:装饰者和被装饰者应该实现同一个类型
public abstract class Reader {
	public abstract void close();
}
public class FileReader extends Reader{

	@Override
	public void close() {
		System.out.println("FileReader closed!");
	}
	
}
public class BufferedReader extends Reader{

	private Reader in;//被装饰者的引用
	
	public BufferedReader(Reader in) {// 多态
		this.in = in;
	}
	
	@Override
	public void close() {
		System.out.println("BufferedReader closed!");
		in.close();
		System.out.println("BufferedReader closed!");
	}

}

数据字节流

DataOutpurStream 和 DataInputStream

数据字节输出流和数据字节输入流是比较专用的流。主要用于存储变量等(用的比较少)

  • DataOutputStream
java.io.OutputStream;
    java.io.FilterOutputStream;
		java.io.DataOutputStream;

数据字节输出流可以将 内存中的 “int i=10;” 写入到硬盘文件中。写进去的不是字符串格式,而是二进制串,带有数据类型。

import java.io.*;
public class Test19 {
	public static void main(String[] args) throws Exception{
		// 创建流
		DataOutputStream dos = new DataOutputStream(new FileOutputStream("./resource/temp06"));
		// 准备数据
		byte b = 10;
		short s = 13;
		int i = 24;
		long l = 123L;
		float f = 0.23f;
		double d = 1.32;
		boolean flag = true;
		char c = 'a';
		// 写
		dos.writeByte(b);
		dos.writeShort(s);
		dos.writeInt(i);
		dos.writeLong(l);
		dos.writeFloat(f);
		dos.writeDouble(d);
		dos.writeBoolean(flag);
		dos.writeChar(c);
		// 刷新
		dos.flush();
		// 关闭
		dos.close();
	}

}
  • DataInputStream
java.io.InputStream;
	java.io.FilterInputStream;
		java.io.DataInputStream;

数据字节输入流:用于读取DataOutputStream写的文件,且必须提前知道该文件中的数据存储格式和存储顺序,读取的顺序必须和写入的顺序相同。

package com.test.inputoutput;
import java.io.*;
public class Test20 {
	public static void main(String[] args) throws Exception{
		DataInputStream dis = new DataInputStream(new FileInputStream("./resource/temp06"));
		byte b = dis.readByte();
		short s = dis.readShort();
		int i = dis.readInt();
		long l = dis.readLong();
		float f = dis.readFloat();
		double d = dis.readDouble();
		boolean flag = dis.readBoolean();
		char c = dis.readChar();
		
		System.out.println(b);
		System.out.println(s);
		System.out.println(i);
		System.out.println(l);
		System.out.println(f);
		System.out.println(d);
		System.out.println(flag);
		System.out.println(c);
		dis.close();
	}
}
//输出
10
13
24
123
0.23
1.32
true
a

打印流

java.io.PrintStream; // 标准输出流,默认打印到控制台,以字节方式

java.io.PrintWriter; // 标准输出流,默认打印到控制台,以字符方式

  • 举例1-使用printStream
import java.io.*;
import java.text.*;
import java.util.*;

public class Test21 {
	public static void main(String[] args) throws Exception{
		// 默认输出到控制台
		System.out.println("hello world");
		PrintStream ps = System.out;
		ps.println("hello world");
		// 可以改变输出方向
		System.setOut(new PrintStream(new FileOutputStream("./resource/logs", true)));// log 文件
		// 输出
		System.out.println("HAHA");
		// 通常使用上面方式记录日志
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");
		System.out.println("m1 方法开始执行"+sdf.format(new Date()));
		m1();
		System.out.println("m1 方法执行结束"+sdf.format(new Date()));
	}
	static void m1() {
		System.out.println("hello");
	}
}

对象流

对象序列化&反序列化

序列化:将堆内存中的对象信息转换为可以存储或者传输的形式的过程(Serial)

反序列化:将硬盘中存储的对象信息加载到JVM内存中(DeSerial)

java.io.ObjectOutputStream; 序列化java对象到硬盘

java.io.ObjectInputStream;将硬盘中的数据“反序列化”到JVM内存

  • 举例1-对象序列化
import java.io.Serializable;

public class User implements Serializable{
    String name;
    public User(String name){
        this.name = name;
    }

    @Override
    public String toString() {
        return "User[name:"+this.name+"]";
    }
}
import java.io.*;

public class Test{
    public static void main(String[] args) throws Exception{
        User u1 = new User("张三");
        User u2 = new User("李四");
        User u3 = new User("王五");
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("temp07"));
        
        oos.writeObject(u1);
        oos.writeObject(u2);
        oos.writeObject(u3);
        // flush
        oos.flush();
        // close
        oos.close();
    }
}
  • 序列化的对象必须实现Serializable接口
  • Serializable接口内没有定义任何方法,将这类接口称为:标识接口
  • 没有任何方法的接口称为标识接口
  • 类似的接口还有java.lang.Clonable
  • 标识接口的作用
  • 起到标识的作用
  • JVM如果看到了某个对象实现了某个标识接口,会对它**“特殊待遇”**
  • 举例2-反序列化
import java.io.*;
public class Test02{
    public static void main(String[] args) throws Exception{
        // 创建反序列化流
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("temp07"));
        // 读
        Object o = ois.readObject();
        System.out.println(o);//User[name:张三]
        o = ois.readObject();
        System.out.println(o);//User[name:李四]
        o = ois.readObject();
        System.out.println(o);//User[name:王五]
        // 关闭
        ois.close();
    }
}

序列化版本号:SerialVersion_UID

考虑这样一种情形:

  • 有一个User类
public class User implements Serializable{
    
}

将该类对应的对象序列化

import java.io.*;

public class Test{
    public static void main(String[] args) throws Exception{
        User u1 = new User();
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("temp07"));
        
        oos.writeObject(u1);

        // flush
        oos.flush();
        // close
        oos.close();
    }
}

编译运行后,对该对象反序列化

  • 但是原先生成 User.class 的类删掉了,原先的 User.java 也重写了,重新编译生成 User.class
public class User implements Serializable{
    String name;
}
  • 反序列化出现错误:
Exception in thread "main" java.io.InvalidClassException: User; 
local class incompatible: 
stream classdesc serialVersionUID = -7020619477594468968, 
local class serialVersionUID = 5211548487022640024

产生的原因:因为 User 类 实现了 Serializable 接口,JVM 会特殊待遇:会给该类添加一个属性:

static final long serialVersionUID=-7020619477594468968

在反序列化的时候,JVM会比较硬盘中存储的对象文件和User.class 中的 SerialVersionUID 是否一样,如果不一样,则会报错。

之前的User.classSerialVersionUID-7020619477594468968; 序列化后存储到硬盘中的SerialVersionUID也是-7020619477594468968;User.java重写后,jvm给它添加的属性SerialVersionUID的值为:5211548487022640024,所以在反序列化的时候出现错误。

如何实现在更改原先的类之后,仍可以反序列化对象呢?

  • 不让JVM自动生成,自己写一个序列化版本号
import java.io.Serializable;

public class User implements Serializable{
    // 手动创建序列化版本号
    static final long serialVersionUID = 123123123L;
    // 下面可以对代码升级
    String name;
    public User(String name){
        this.name = name;
    }
}
  • 如果不想让类中的某一个属性序列化,可以在属性前面添加transient关键字修饰
import java.io.Serializable;

public class User implements Serializable{
    // 序列化版本号
    static final long serialVersionUID = 123123123L;
    // 下面可以对代码升级
    transient String name; // transient 短暂的,暂时的
    public User(String name){
        this.name = name;
    }
    @Override
    public String toString() {
        return "User[name="+this.name+"]";
    }
}

反序列化得到结果:

User[name=null]

File 类

  • 继承结构
java.lang.Object;
	java.io.File;
  • File和流没有关系,通过File不能完成文件的读和写
  • File 是 文件和目录路径名的抽象表现形式
  • 代表的硬盘上的文件夹(Directory)和文件(File)
  • 举例1-File中的常用方法
import java.io.File;
import java.util.*;
import java.text.*;
public class Test01 {
	public static void main(String[] args) throws Exception{
		String parentPath = "D:\\CodeFiles\\CodeTrain\\code_train\\resource";
		File f1 = new File(parentPath);
		// 1. 判断是否存在
		System.out.println(f1.exists());// true
		// 2. 创建新文件
		File newFile = new File("newFile.java");
		System.out.println(newFile.createNewFile());// true
		// 3.获取新文件对应的绝对路径
		File newFile2 = newFile.getAbsoluteFile();
		System.out.println(newFile2.getAbsolutePath());
		// 4.获得文件名
		System.out.println(newFile.getName());
		// 5. 获得父目录
		System.out.println(newFile2.getAbsoluteFile().getParent());
		// 6. 判断文件路径是否是绝对路径
		System.out.println(newFile.getAbsoluteFile().isAbsolute());// true
		// 7.判断是否是目录
		System.out.println(newFile.isDirectory());// false
		// 8.判断是否是文件
		System.out.println(newFile.isFile());// true
		// 9.判断文件是否是隐藏文件
		System.out.println(newFile.isHidden()); // false
		// 10.获取文件最后一次更改的时间
		long time = newFile.lastModified();
		Date date = new Date(time);
		System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS").format(date));//2020-03-17 17:50:25 084
		// 11.获取文件对应的长度(大小/字节)
		System.out.println(newFile.length());// 0
		System.out.println(newFile.getAbsoluteFile().getParent().length());//33
		// 12. 获取该目录下的所有文件/目录
		String[] names = new File(newFile.getAbsoluteFile().getParent()).list();
		for(String str:names) {
			System.out.println(str);
		}
		File[] files = new File(newFile.getAbsoluteFile().getParent()).listFiles();
		for(File file:files) {
			System.out.println(file.getAbsolutePath());
		}
		// 13.在指定目录下创建目录
		File newD = new File(newFile.getParentFile(), "test_dir");
		if(! newD.exists()) {
			newD.mkdir();
		}
		System.out.println(newD.getAbsolutePath());
		// 14. 删除对应目录
		System.out.println(newD.delete());
		// 15.创建多层目录
		File multi_dir = new File(newFile.getParentFile(), "a/b/v/c/d/f");
		if(!multi_dir.exists()) {
			multi_dir.mkdirs();
		}
		System.out.println(multi_dir.getAbsolutePath());
		
	}
}
  • 举例2-递归遍历目录下所有文件
import java.io.*;
public class Test02 {
	public static void main(String[] args) {
		String parentPath = "D:\\CodeFiles";
		File f = new File(parentPath);
		getFilesR(f);
	}

	private static void getFilesR(File f) {
		if(f.isFile()) {
			return;
		}
		File[] files = f.listFiles();
		for(File file:files) {
			System.out.println(file);
			getFilesR(file);
		}
		
	}
}

以上