抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

File类

  1. File 类位于 java.io 包下

  2. File 类的一个对象,对应与操作系统下的一个文件或一个文件目录(或文件夹)

  3. File 能新建、删除、重命名文件和目录,但是不能访问文件本身,若需要访问文件内容,需要使用输入/输出流

常用方法

获取文件和目录基本信息

1
2
3
4
5
6
7
public String getAbsolutePath():返回文件的绝对路径,包括文件名
public File getAbsoluteFile():返回表示文件绝对路径的 File 对象
public String getName():返回文件或目录的名称
public String getParent():返回文件或目录的父目录的路径,如果没有父目录,则返回 null
public String getPath():返回文件或目录的路径,相对路径或绝对路径都可能
public long length():返回文件的长度,以字节为单位
public long lastModified(): 返回文件的上一次修改时间,以毫秒为单位的时间戳

当文件不存在时返回结果如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
public class Main {
public static void main(String[] args) {
File file = new File("hello.txt");
System.out.println(file.getAbsolutePath()); // E:\Code\Java_Code\Java_Study\hello.txt
System.out.println(file.getAbsoluteFile()); // E:\Code\Java_Code\Java_Study\hello.txt
System.out.println(file.getName()); // hello.txt
System.out.println(file.getParent()); // null
System.out.println(file.getPath()); // hello.txt
System.out.println(file.getAbsoluteFile().getParent()); // E:\Code\Java_Code\Java_Study
System.out.println(file.length()); // 0
System.out.println(file.lastModified()); // 0
}
}

当文件存在时返回结果如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
public class Main {
public static void main(String[] args) {
File file = new File("hello.txt");
System.out.println(file.getAbsolutePath()); // E:\Code\Java_Code\Java_Study\hello.txt
System.out.println(file.getAbsoluteFile()); // E:\Code\Java_Code\Java_Study\hello.txt
System.out.println(file.getName()); // hello.txt
System.out.println(file.getParent()); // null
System.out.println(file.getPath()); // hello.txt
System.out.println(file.getAbsoluteFile().getParent()); // E:\Code\Java_Code\Java_Study
System.out.println(file.length()); // 12
System.out.println(file.lastModified()); // 1714288336594
}
}

列出下一级目录

1
2
3
4
5
public String[] list():返回目录中所有文件和子目录的名称数组,如果目录为空或者不是一个目录,则返回 null
public String[] list(FilenameFilter f):返回目录中满足指定文件名过滤器条件的文件和子目录的名称数组,参数 f 是一个文件名过滤器,用于筛选文件和子目录,如果目录为空、不是目录,或者没有匹配的文件和子目录,则返回 null
public File[] listFiles():返回表示目录中所有文件和子目录的 File 对象数组,如果目录为空或者不是一个目录,则返回 null
public File[] listFiles(FilenameFilter f):返回表示目录中满足指定文件名,参数 f 是一个文件名过滤器,用于筛选文件和子目录,如果目录为空、不是目录,或者没有匹配的文件和子目录,则返回 null
public File[] listFiles(FileFilter f):返回表示目录中满足指定文件过滤器条件的文件和子目录的 File 对象数组,参数 f 是一个文件过滤器,用于筛选文件和子目录,如果目录为空、不是目录,或者没有匹配的文件和子目录,则返回 null
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class Main {
public static void main(String[] args) throws IOException {
File file = new File("E:\\Code\\Java_Code");
String[] list = file.list();
for (String str : list) {
System.out.println(str);
}

File[] files = file.listFiles();
for (File listFile : files) {
System.out.println(listFile);
System.out.println(listFile.getName());
}
}
}

重命名功能

1
public boolean renameTo(File destination):把文件重命名为指定的文件路径,返回一个 bool 值

想要成功重命名文件,file 必须存在,file1 不能存在, file1 所在的目录必须存在

1
2
3
4
5
6
7
8
public class Main {
public static void main(String[] args) {
File file = new File("hello.txt");
File file1 = new File("E:\\Code\\Java_Code\\0428\\0428.txt");
boolean result = file.renameTo(file1);
System.out.println(result ? "重命名成功" : "重命名失败");
}
}

判断功能

1
2
3
4
5
6
public boolean exists():此 File 表示的文件或目录是否实际存在
public boolean isDirectory()::此 File 表示的是否为目录。
public boolean isFile():此 File 表示的是否为文件
public boolean canRead():判断是否可读
public boolean canWrite():判断是否可写
public boolean isHidden():判断是否隐藏

当文件或目录不存在时,以下方法的 Bool 值全为Flase

1
2
3
4
5
6
7
8
9
10
11
public class Main {
public static void main(String[] args) {
File file = new File("E:\\Code\\Java_Code\\0428\\0428.txt");
System.out.println(file.exists()); //true
System.out.println(file.isDirectory()); //false
System.out.println(file.isFile()); //true
System.out.println(file.canRead()); //true
System.out.println(file.canWrite()); //true
System.out.println(file.isHidden()); //false
}
}

创建删除

1
2
3
4
public boolean createNewFile():创建文件。若文件存在,则不创建,返回false
public boolean mkdir():创建文件目录。如果此文件目录存在,就不创建了。如果此文件目录的上层目录不存在,也不创建
public boolean mkdirs():创建文件目录。如果上层文件目录不存在,一并创建
public boolean delete():删除文件或者文件夹。删除注意事项:① Java 中的删除不走回收站。② 要删除一个文件目录,请注意该文件目录内不能包含文件或者文件目录
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class Main {
public static void main(String[] args) throws IOException {
File file = new File("E:\\Code\\Java_Code\\0428\\0428.txt");
if (!file.exists()) {
boolean isSuccessed = file.createNewFile();
if (isSuccessed){
System.out.println("创建成功");
}
}else {
System.out.println("此文件已存在");
boolean delete = file.delete();
System.out.println(delete ? "文件删除成功" : "文件删除失败");
}
}
}

IO流

当完成流的操作时,必须调用 close()方法,释放系统资源,否则会造成内存泄漏

分类

数据流向不同可分为:

  • 输入流:把数据从其他设备上读取到内存中的流

  • 输出流:把数据从内存中写出到其他设备上的流

操作单位不同可分为:

  • 字节流:以字节为单位,读写数据的流

  • 字符流:以字符为单位,读写数据的流

IO流角色不同可分为:

  • 节点流:从数据源或目的地读写数据

  • 处理流:不直接连接到数据源或目的地,而是连接在已存在的流(节点流或处理流)之上,通过对数据的处理为程序提供更为强大的读写功能

API

IO流涉及40多个类,实际上非常常规,都是从如下四个抽象基类派生的

抽象基类 输入流 输出流
字节流 InputStream OutputStream
字符流 Reader Writer

由四个抽象基类派生类

分类 字节输入流 字节输出流 字符输入流 字符输出流
抽象基类 InputStream OutputStream Reader Writer
访问文件 FileInputStream FileOutputStream FileReader FileWriter
访问数组 ByteArrayInputStream ByteArrayOutputStream CharArrayReader CharArrayWriter
访问管道 PipedInputStream PipedOutputStream PipedReader PipedWriter
访问字符串 StringReader StringWriter
缓冲流 BufferedInputStream BufferedOutputStream BufferedReader BufferedWriter
转换流 InputStreamReader InputStreamWriter
对象流 ObjectInputStream ObjectOutputStream
FilterInputStream FilterOutputStream FilterReader FilterWriter
打印流 PrintStream PrintWriter
推回输入流 PushbackInputStream PushbackReader
特殊流 DataInputStream DataOutputStream

常用节点流

  • 文件流:FileInputStream、FileOutputStrean、FileReader、FileWriter

  • 字节/字符数组流:ByteArrayInputStream、ByteArrayOutputStream、CharArrayReader、CharArrayWriter

常用处理流

  • 缓冲流:BufferedInputStream、BufferedOutputStream、BufferedReader、BufferedWriter

  • 转换流:InputStreamReader、OutputStreamReader

  • 对象流:ObjectInputStream、ObjectOutputStream

文件流

Reader and Writer

Reader-说明

java.io.Reader抽象类是用于读取字符流的所有类的父类,可以读取字符信息到内存中。它定义了字符输入流的基本共性功能方法

1
2
3
4
public int read():从输入流读取一个字符。虽然读取了一个字符,但是会自动提升为 int 类型。返回该字符的 Unicode 编码值。如果已经到达流末尾了,则返回-1
public int read(char[] cbuf): 从输入流中读取一些字符,并将它们存储到字符数组 cbuf 中 。每次最多读取 cbuf.length 个字符。返回实际读取的字符个数。如果已经到达流末尾,没有数据可读,则返回-1
public int read(char[] cbuf,int off,int len):从输入流中读取一些字符,并将它们存储到字符数组 cbuf 中,从 cbuf[off]开始的位置存储。每次最多读取len 个字符。返回实际读取的字符个数。如果已经到达流末尾,没有数据可读,则返回-1
public void close():关闭此流并释放与此流相关联的任何系统资源

Writer-说明

java.io.Writer 抽象类是表示用于写出字符流的所有类的超类,将指定的字符信息写出到目的地。它定义了字节输出流的基本共性功能方法

1
2
3
4
5
6
7
public void write(int c):写出单个字符。
public void write(char[] cbuf):写出字符数组。
public void write(char[] cbuf, int off, int len):写出字符数组的某一部分。off:数组的开始索引;len:写出的字符个数。
public void write(String str):写出字符串。
public void write(String str, int off, int len) :写出字符串的某一部分。off:字符串的开始索引;len:写出的字符个数。
public void flush():刷新该流的缓冲。
public void close():关闭此流。

FileReader and FileWriter

  • 字符流只能用来操作文本文件,不能用来处理非文本文件

  • 流资源的调用,为避免内存泄漏,需要使用 try-catch-finally 处理异常

FileReader-说明

  • 用于读取字符文件,构造时使用系统默认的字符编码和默认字节缓冲区
1
2
FileReader(File file):创建一个新的 FileReader ,给定要读取的 File 对象
FileReader(String fileName):创建一个新的 FileReader ,给定要读取的文件的名称

FileWriter-说明

  • 用于写出字符到文件,构造时使用系统默认的字符编码

  • 构造器中可指定是否覆盖原有文件 ***FileWriter(File file,false)***,默认为 flase,为true时追加在文件末尾

1
2
3
FileWriter(File file):创建一个新的 FileWriter,给定要读取的 File 对象
FileWriter(String fileName):创建一个新的 FileWriter,给定要读取的文件的名称
FileWriter(File file,boolean append):创建一个新的 FileWriter,指明是否在现有文件末尾追加内容

案例

案例1-将磁盘文件 hello.txt 写入至内存中
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
public class Main {
public static void main(String[] args) {
FileReader fileReader = null;
try {
// 创建File类对象,对应hello.txt
File file = new File("hello.txt");

// 创建字符输入流
fileReader = new FileReader(file);

// 读取hello.txt,并显示在控制台上
char[] cbuffer = new char[5];
int len;

while ((len = fileReader.read(cbuffer)) != -1) {
for (int i = 0; i < cbuffer.length; i++) {
System.out.print(cbuffer[i]);
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
// 流资源关闭操作(必须要关闭,否则会内存泄漏)
try {
if (fileReader != null)
fileReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

上述代码中会存在一个问题,文件内容为 “hello world” 而最后遍历出的内容为: “hello worldworl”,这是由于只有11个字符,一次性搬运5个字符,总共需要运三趟。第一次搬运字符为”hello”,第二次为” worl”,第三次为”dworl”,因为它每一趟回去都是覆盖上一次的字符串, 而到第三趟时,字符串只剩下一个了,也就只覆盖一个,然后遍历时遍历的是数组的长度,所以会出现这种错误。

1
2
3
4
5
while ((len = fileReader.read(cbuffer)) != -1) {
for (int i = 0; i < len; i++) {
System.out.print(cbuffer[i]);
}
}

将其中的 “cbuffer.length” 改为 “len” 即可解决问题,通过每次读多少个就遍历多少次。

案例2-复制磁盘文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
public class Main {
public static void main(String[] args) {
FileReader fileReader = null;
FileWriter fileWriter = null;
try {
File file = new File("hello.txt");
File file1 = new File("hello_copy.txt");

// 创建字符输入输出流
fileReader = new FileReader(file);
fileWriter = new FileWriter(file1);

// 读取hello.txt
char[] cbuffer = new char[5];
int len;
while ((len = fileReader.read(cbuffer)) != -1) {
fileWriter.write(cbuffer, 0, len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
// 关闭输入输出流
try{
if (fileWriter != null)
fileWriter.close();
} catch (IOException e){
e.printStackTrace();
}
try {
if (fileReader != null)
fileReader.close();
}catch (IOException e){
e.printStackTrace();
}
}
}
}

InputStream and OutputStream

InputStream-说明

java.io.InputStream 抽象类是表示字节输入流的所有类的超类,可以读取字节信息到内存中。它定义了字节输入流的基本共性功能方法

1
2
3
4
public int read():从输入流读取一个字节。返回读取的字节值。虽然读取了一个字节,但是会自动提升为 int 类型。如果已经到达流末尾,没有数据可读,则返回-1
public int read(byte[] b):从输入流中读取一些字节数,并将它们存储到字节数组 b 中 。每次最多读取 b.length 个字节。返回实际读取的字节个数。如果已经到达流末尾,没有数据可读,则返回-1
public int read(byte[] b,int off,int len):从输入流中读取一些字节数,并将它们存储到字节数组 b 中,从 b[off]开始存储,每次最多读取 len 个字节 。返回实际读取的字节个数。如果已经到达流末尾,没有数据可读,则返回-1
public void close():关闭此输入流并释放与此流相关联的任何系统资源

OutputStream-说明

java.io.OutputStream 抽象类是表示字节输出流的所有类的超类,将指定的字节信息写出到目的地。它定义了字节输出流的基本共性功能方法

1
2
3
4
5
public void write(int b):将指定的字节输出流。虽然参数为 int 类型四个字节,但是只会保留一个字节的信息写出
public void write(byte[] b):将 b.length 字节从指定的字节数组写入此输出流
public void write(byte[] b, int off, int len):从指定的字节数组写入 len 字节,从偏移量 off 开始输出到此输出流
public void flush():刷新此输出流并强制任何缓冲的输出字节被写出
public void close():关闭此输出流并释放与此流相关联的任何系统资源。说明:close()方法,当完成流的操作时,必须调用此方法,释放系统资源

FileInputStream and FileOutputStream

字节流通常是用来处理非文本文件的。若涉及到文本文件的复制操作,也可以使用字节流。但是若是传输途中查看可能会出现乱码情况。

FileInputStream-说明

java.io.FileInputStream 类是文件输入流,从文件中读取字节

1
2
FileInputStream(File file):通过打开与实际文件的连接来创建一个 FileInputStream ,该文件由文件系统中的 File 对象 file 命名. 
FileInputStream(String name):通过打开与实际文件的连接来创建一个 FileInputStream ,该文件由文件系统中的路径名 name 命名。

FileOutputStream-说明

java.io.FileOutputStream 类是文件输出流,用于将数据写出到文件

1
2
3
public FileOutputStream(File file):创建文件输出流,写出由指定的 File对象表示的文件
public FileOutputStream(String name):创建文件输出流,指定的名称为写出文件
public FileOutputStream(File file, boolean append):创建文件输出流,指明是否在现有文件末尾追加内容

案例-复制一张图片

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
public class Main {
public static void main(String[] args) throws IOException {
FileInputStream fileInputStream = null;
FileOutputStream fileOutputStream = null;
try {
// 创建相关的File类对象
File file = new File("test.jpg");
File file1 = new File("test_copy.jpg");

// 创建相关的字节流
fileInputStream = new FileInputStream(file);
fileOutputStream = new FileOutputStream(file1);

// 数据的读入和写出
byte[] buffer = new byte[1024];
int len;

while ((len = fileInputStream.read(buffer)) != -1) {
fileOutputStream.write(buffer, 0, len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
// 关闭资源
try {
if (fileInputStream != null) {
fileInputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
try {
if (fileOutputStream != null) {
fileOutputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

处理流

缓冲流

缓冲流的作用为:提升文件读写效率

缓冲流的原理为:在创建流对象时,内部会创建一个缓冲区数组(缺省使用 8192个字节(8Kb)的缓冲区),通过缓冲区读写,减少系统 IO 次数,从而提高读写的效率

整体使用其实与文件流无太大区别,只是在文件传输流外包裹了一个缓冲流,数据读取写入时也是用缓冲流进行操作。关闭流资源时先关闭外层再关闭内存,但是外层关闭后会自动关闭内层流,所以可以省略关闭内存流的操作。

BufferedInputStream and BufferedOutputStream

字节缓冲流

1
2
public BufferedInputStream(InputStream in):创建一个新的字节型的缓冲输入流
public BufferedOutputStream(OutputStream out):创建一个新的字节型的缓冲输出流
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
public class Main {
public static void main(String[] args) {
BufferedInputStream bufferedInputStream = null;
BufferedOutputStream bufferedOutputStream = null;
try {
File file = new File("test.jpg");
File file1 = new File("test_copy.jpg");

// 字节流
FileInputStream fileInputStream = new FileInputStream(file);
FileOutputStream fileOutputStream = new FileOutputStream(file1);

// 缓冲流
bufferedInputStream = new BufferedInputStream(fileInputStream);
bufferedOutputStream = new BufferedOutputStream(fileOutputStream);

// 数据读入和写出
byte[] buffer = new byte[1024];
int len;
while ((len = bufferedInputStream.read(buffer)) != -1) {
bufferedOutputStream.write(buffer, 0, len);
}
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
// 关闭资源,先关外层,再关内层
try {
if (bufferedOutputStream != null) {
bufferedOutputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}

try {
if (bufferedInputStream != null) {
bufferedInputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

BufferedReader and BufferedWriter

字符缓冲流

1
2
BufferedReader:public String readLine():读一行文字
BufferedWriter:public void newLine():写一行行分隔符,由系统属性定义符号

readLine方法是缓冲流特有的方法,其按行读取,且不读取换行 \n,当读取完后会返回 NULL

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
public class Main {
public static void main(String[] args) {
FileReader fileReader = null;
try {
File file = new File("hello.txt");

// 字符流
fileReader = new FileReader(file);

// 缓冲流
BufferedReader bufferedReader = new BufferedReader(fileReader);

char[] cbuffer = new char[5];
int len;

while ((len = bufferedReader.read(cbuffer)) != -1) {
System.out.println(new String(cbuffer, 0, len));
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (fileReader != null) {
fileReader.close();
}
}catch (IOException e){
e.printStackTrace();
}
}
}
}

案例-读取大型txt文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
public class Main {
public static void main(String[] args) {
BufferedReader bufferedReader = null;
BufferedWriter bufferedWriter = null;
try {
File file = new File("hello.txt");
File file1 = new File("hello_copy.txt");

// 字符流
FileReader fileReader = new FileReader(file);
FileWriter fileWriter = new FileWriter(file1);

// 缓冲流
bufferedReader = new BufferedReader(fileReader);
bufferedWriter = new BufferedWriter(fileWriter);

// 读取数据并写入数据,使用readline一行行读取,一行行写入
String data;
while ((data = bufferedReader.readLine()) != null) {
bufferedWriter.write(data + "\n");
}
} catch (IOException e) {
e.printStackTrace();
} finally {
// 异常关闭
try {
if (bufferedReader != null) {
bufferedReader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
try {
if (bufferedWriter != null) {
bufferedWriter.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}