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

摘要:本文学习了如何使用输入输出流对文件进行操作。

环境

Windows 10 企业版 LTSC 21H2
Java 1.8

1 文件

1.1 概念

File类是数据源的一种,可以表示一个文件,也可以表示一个文件目录。

File类只能对文件和目录进行创建和删除等操作,可以查看文件和目录的属性,不能读取或修改内容。如果需要读取或修改文件的内容,需要使用输入输出流。

常常将File类的对象作为参数传递到输入输出流的类的构造器中。

绝对路径和相对路径:

  • 相对路径:相对路径名必须使用取自其他路径名的信息进行解释。
  • 绝对路径:绝对路径名是完整的路径名,不需要任何其他信息就可以定位它所表示的文件或目录。

相对路径创建的实例不等于绝对路径创建的实例。

1.2 常用方法

查看文件和目录:

java
1
2
3
4
5
6
// 获得文件名或目录名
String getName();
// 获得相对路径
String getPath();
// 获得绝对路径
String getAbsolutePath();

创建和删除文件和目录:

java
1
2
3
4
5
6
7
8
// 创建一个空文件
boolean createNewFile();
// 创建一个空目录
boolean mkdir();
// 创建指定的目录及父目录
boolean mkdirs();
// 删除文件或空目录
boolean delete();

常用的判断方法:

java
1
2
3
4
5
6
// 判断是否存在
boolean exists();
// 判断是否目录
boolean isDirectory();
// 判断是否文件
boolean isFile();

1.3 常量

1.3.1 名称分隔符

使用File.separator获取与系统有关的名称分隔符字符串,此字符串只包含separatorChar字符,用于分隔路径中的文件和目录。

separatorChar被初始化为包含系统属性file.separator值的第一个字符。在UNIX系统上对应/符号,在Windows系统上对应\符号。

1.3.2 路径分隔符

使用File.sepapathSeparatorrator获取与系统有关的路径分隔符字符串,此字符串只包含pathSeparatorChar字符,用于分隔以路径列表中的路径。

pathSeparatorChar被初始为包含系统属性path.separator值的第一个字符。在UNIX系统上对应:符号,在Windows系统上对应;符号。

2 输入输出流

2.1 概念

流是数据在数据源(文件)和程序(内存)之间经历的路径。

输入输出流可以称为IO流,I即输入流,O即输出流。流的方向以内存为参照,如果数据流向内存流动则是输入流,反之则是输出流。

文件和目录在程序中是以流的形式来操作的,凡是与输入输出相关的都定义在java.io包下。

打开的资源不属于内存里的资源,垃圾回收机制无法回收该资源,所以应该显式关闭。关闭流时只需要考虑关闭最外层的流即可,如果要强制关闭所有流,必须先关闭外层的流。

在JDK1.7之后,可以在try-catch代码块中打开流,最后程序会自动关闭流对象。

2.2 分类

按数据流的流向:输入流,输出流。

按操作数据单位:字节流(InputStream、OutputStream),字符流(Reader、Writer)。

按流的角色:节点流,处理流。

3 文件流

文件流主要有:FileInputStream、FileOutputStream、FileReader、FileWriter。

这四个类用于操作文件流,用法高度相似,前面两个操作字节流,后面两个操作字符流。

文件流直接与操作系统底层交互,因此也被称为节点流,节点流需要关流。

3.1 FileInputStream

构造方法:

java
1
2
FileInputStream(File file);
FileInputStream(String name);

常用方法:

java
1
2
3
4
5
6
7
8
// 从输入流中读入一个字节
int read();
// 从输入流中读入到数组
int read(byte[] b);
// 从输入流中将len个数据读入到数组
int read(byte[] b, int off, int len);
// 关闭输入流并释放系统资源
void close();

读入文件到输入流:

java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public void test() {
FileInputStream fis = null;
try {
fis = new FileInputStream(new File("D:" + File.separator + "hello.txt"));
byte[] buffer = new byte[1024];
int len = 0;
String txt = "";
while ((len = fis.read(buffer)) != -1) {
txt += new String(buffer, 0, len);
}
System.out.println(txt);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

3.2 FileOutputStream

构造方法:

java
1
2
3
4
FileOutputStream(File file);
FileOutputStream(File file, boolean append);
FileOutputStream(String name);
FileOutputStream(String name, boolean append);

常用方法:

java
1
2
3
4
5
6
7
8
9
10
// 从指定字节中写出到输出流
void write(int b);
// 从数组中写出到输出流
void write(byte[] b);
// 从数组中将len个数据写出到输出流
void write(byte[] b, int off, int len);
// 刷新该流的缓冲
void flush();
// 关闭输出流并释放系统资源
void close();

读出文件到输出流:

java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public void test() {
FileOutputStream fos = null;
try {
fos = new FileOutputStream(new File("D:" + File.separator + "hello.txt"));
fos.write("hello".getBytes());
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

3.3 FileReader

构造方法:

java
1
2
FileReader(File file);
FileReader(String fileName);

常用方法:

java
1
2
3
4
5
6
7
8
9
10
// 返回此流使用的字符编码的名称
String getEncoding();
// 从输入流中读入一个字节
int read();
// 从输入流中读入到数组
int read(char[] cbuf);
// 从输入流中将len个数据读入到数组
int read(char[] cbuf, int off, int len);
// 关闭输入流并释放系统资源
void close();

读入文本到输入流:

java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public void test() {
FileReader fr = null;
try {
fr = new FileReader(new File("D:" + File.separator + "hello.txt"));
char[] buffer = new char[1024];
int len = 0;
String txt = "";
while ((len = fr.read(buffer)) != -1) {
txt = new String(buffer, 0, len);
}
System.out.print(txt);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fr != null) {
try {
fr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

3.4 FileWriter

构造方法:

java
1
2
3
4
FileWriter(File file);
FileWriter(File file, boolean append);
FileWriter(String fileName);
FileWriter(String fileName, boolean append);

常用方法:

java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 返回此流使用的字符编码的名称
String getEncoding();
// 从指定字节中写出到输出流
void write(int b);
// 从数组中写出到输出流
void write(byte[] b);
// 从数组中将len个数据写出到输出流
void write(byte[] b, int off, int len);
// 从字符串中写出到输出流
void write(String str);
// 从字符串中将len个数据写出到输出流
void write(String str, int off, int len);
// 刷新该流的缓冲
void flush();
// 关闭输出流并释放系统资源
void close();

读出文本到输出流:

java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public void test() {
FileWriter fw = null;
try {
fw = new FileWriter(new File("D:" + File.separator + "hello.txt"));
fw.write("hello");
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fw != null) {
try {
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

3.5 复制文件

使用字节流复制文件:

java
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
public void test() {
FileInputStream fis = null;
FileOutputStream fos = null;
try {
fis = new FileInputStream("D:" + File.separator + "old.jpeg");
fos = new FileOutputStream("D:" + File.separator + "new.jpeg");
byte[] buffer = new byte[1024];
int len = 0;
while ((len = fis.read(buffer)) != -1) {
fos.write(buffer, 0, len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

使用字符流复制文件:

java
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
public void test() {
FileReader fr = null;
FileWriter fw = null;
try {
fr = new FileReader("D:" + File.separator + "old.txt");
fw = new FileWriter("D:" + File.separator + "new.txt");
char[] buffer = new char[1024];
int len = 0;
while ((len = fr.read(buffer)) != -1) {
fw.write(buffer, 0, len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fr != null) {
try {
fr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fw != null) {
try {
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

4 缓冲流

缓冲流主要有:BufferedInputStream、BufferedOutputStream、BufferedReader、BufferedWriter。

这四个类可以封装现有的节点流,实现对数据传输的效率的提升。

缓冲流比文件流多了一个缓冲区,读取时先从缓冲区读取,当缓冲区数据读完时再把数据写入到缓冲区。因此,当每次读取的数据量很小时,文件流从硬盘读入,缓冲流从缓冲区读入。读取内存速度比读取硬盘速度快得多,因此缓冲流效率高。

缓冲流的默认缓冲区大小是8192字节,当每次读取数据量接近或远超这个值时,两者效率就没有明显差别了。

缓冲流属于处理流,处理流需要关流。

4.1 BufferedInputStream

构造方法:

java
1
2
BufferedInputStream(InputStream in);
BufferedInputStream(InputStream in, int size);

常用方法:

java
1
2
3
4
5
6
7
8
// 从输入流中读入一个字节
int read();
// 从输入流中读入到数组
int read(byte[] b);
// 从输入流中将len个数据读入到数组
int read(byte[] b, int off, int len);
// 关闭输入流并释放系统资源
void close();

4.2 BufferedOutputStream

构造方法:

java
1
2
BufferedOutputStream(OutputStream out);
BufferedOutputStream(OutputStream out, int size);

常用方法:

java
1
2
3
4
5
6
7
8
9
10
// 从指定字节中写出到输出流
void write(int b);
// 从数组中写出到输出流
void write(byte[] b);
// 从数组中将len个数据写出到输出流
void write(byte[] b, int off, int len);
// 刷新该流的缓冲
void flush();
// 关闭输出流并释放系统资源
void close();

4.3 BufferedReader

构造方法:

java
1
2
BufferedReader(Reader in);
BufferedReader(Reader in, int size);

常用方法:

java
1
2
3
4
5
6
7
8
// 从输入流中读入一个字节
int read();
// 从输入流中读入到数组
int read(char[] cbuf);
// 从输入流中将len个数据读入到数组
int read(char[] cbuf, int off, int len);
// 关闭输入流并释放系统资源
void close();

4.4 BufferedWriter

构造方法:

java
1
2
BufferedWriter(Writer out);
BufferedWriter(Writer out, int size);

常用方法:

java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 从指定字节中写出到输出流
void write(int c);
// 从数组中写出到输出流
void write(char[] cbuf);
// 从数组中将len个数据写出到输出流
void write(char[] cbuf, int off, int len);
// 从字符串中写出到输出流
void write(String str);
// 从字符串中将len个数据写出到输出流
void write(String str, int off, int len);
// 刷新该流的缓冲
void flush();
// 关闭输出流并释放系统资源
void close();

4.5 复制文件

使用字节流复制文件:

java
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
public void test() {
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
try {
bis = new BufferedInputStream(new FileInputStream("D:" + File.separator + "old.mp3"));
bos = new BufferedOutputStream(new FileOutputStream("D:" + File.separator + "new.mp3"));
byte[] buffer = new byte[1024];
int len = 0;
while ((len = bis.read(buffer)) != -1) {
bos.write(buffer, 0, len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (bis != null) {
try {
bis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (bos != null) {
try {
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

使用字符流复制文件:

java
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
public void test() {
BufferedReader br = null;
BufferedWriter bw = null;
try {
br = new BufferedReader(new FileReader("D:" + File.separator + "old.txt"));
bw = new BufferedWriter(new FileWriter("D:" + File.separator + "new.txt"));
char[] buffer = new char[1024];
int len = 0;
while ((len = br.read(buffer)) != -1) {
bw.write(buffer, 0, len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (bw != null) {
try {
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

5 转换流

转换流主要有:InputStreamReader、OutputStreamWriter。

这两个流可以将文本在字节流和字符流之间进行转换,但只能处理文本文件。

转换流需要关流。

5.1 InputStreamReader

构造方法:

java
1
2
InputStreamReader(InputStream in);
InputStreamReader(InputStream in, String charsetName);

常用方法:

java
1
2
3
4
5
6
7
8
9
10
// 返回此流使用的字符编码的名称
String getEncoding();
// 从输入流中读入一个字节
int read();
// 从输入流中读入到数组
int read(char[] cbuf);
// 从输入流中将len个数据读入到数组
int read(char[] cbuf, int off, int len);
// 关闭输入流并释放系统资源
void close();

5.2 OutputStreamWriter

构造方法:

java
1
2
OutputStreamWriter(OutputStream out);
OutputStreamWriter(OutputStream out, String charsetName);

常用方法:

java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 返回此流使用的字符编码的名称
String getEncoding();
// 从指定字节中写出到输出流
void write(int c);
// 从数组中写出到输出流
void write(char[] cbuf);
// 从数组中将len个数据写出到输出流
void write(char[] cbuf, int off, int len);
// 从字符串中写出到输出流
void write(String str);
// 从字符串中将len个数据写出到输出流
void write(String str, int off, int len);
// 刷新该流的缓冲
void flush();
// 关闭输出流并释放系统资源
void close();

5.3 复制文件

使用转换流复制文件:

java
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
public void test() {
InputStreamReader isr = null;
OutputStreamWriter osw = null;
try {
isr = new InputStreamReader(new FileInputStream("D:" + File.separator + "old.txt"), "UTF-8");// 确定解码集
osw = new OutputStreamWriter(new FileOutputStream("D:" + File.separator + "new.txt"), "UTF-8");// 确定编码集
char[] buffer = new char[20];
int len = 0;
while ((len = isr.read(buffer)) != -1) {
osw.write(buffer, 0, len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (isr != null) {
try {
isr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (osw != null) {
try {
osw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

6 内存读写流

内存读写流主要有:ByteArrayOutputStream、ByteArrayInputStream。

内存读写流将数组当作流输入输出对象的类。

不同于指向硬盘的流,它内部是使用字节数组读内存的,这个字节数组是它的成员变量,当这个数组不再使用变成垃圾时会被回收,所以内存读写流不需要关流。

6.1 ByteArrayInputStream

构造方法:

java
1
2
ByteArrayInputStream(byte[] b);
ByteArrayInputStream(byte[] b, int off, int len);

常用方法:

java
1
2
3
4
// 从输入流中读入一个字节
int read();
// 从输入流中将len个数据读入到数组
int read(byte[] b, int off, int len);

6.2 ByteArrayIOutputStream

构造方法:

java
1
2
ByteArrayIOutputStream();
ByteArrayIOutputStream(int size);

常用方法:

java
1
2
3
4
5
6
7
8
9
10
11
12
// 从指定字节中写出到输出流
void write(int b);
// 从数组中将len个数据写出到输出流
void write(byte[] b, int off, int len);
// 将缓冲区内容转换字节数组
byte toByteArray();
// 将缓冲区内容转换为字符串
String toString();
// 将缓冲区内容转换为指定编码格式的字符串
String toString(String charsetName);
// 将缓冲区内容输出到指定的输出流
void writeTo(OutputStream out);

6.3 解决乱码

当用字节数组读取字符串时,受数组长度的影响,导致产生乱码。

如果用String类型接收,则不能完全解析出正常的文字,需要使用字节数组输出流将字节数组的内容输出到缓冲区,待读取完成后再转换为String类型的字符串。

示例:

java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public void test() {
ByteArrayInputStream bais = null;
ByteArrayOutputStream baos = null;
try {
bais = new ByteArrayInputStream("测试写入内容".getBytes());
baos = new ByteArrayOutputStream();
byte[] buffer = new byte[1];
int len = -1;
String txt = "";
while ((len = bais.read(buffer)) != -1) {
baos.write(buffer, 0, len);
txt += new String(buffer, 0, len);
}
System.out.println("正常:" + baos.toString());
System.out.println("乱码:" + txt);
} catch (IOException e) {
e.printStackTrace();
}
}

7 标准流

7.1 System.in

可以获取键盘输入的值,属于字节流。

获取方式:

java
1
static InputStream in;

7.2 System.out

可以将文本从控制台输出,属于字节流。

PrintStream是FileOutputStream下的子类,而FileOutputStream是OutputStream下的子类。

获取方式:

java
1
static PrintStream out;

7.3 读取输入内容

从控制台中读取输入内容:

java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public void test() {
BufferedReader br = null;
try {
br = new BufferedReader(new InputStreamReader(System.in));
System.out.println("请输入字符串:");
System.out.println("输入的字符串为:" + br.readLine());
} catch (IOException e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

7.4 读取文件内容

从文件中读取输入内容:

java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public void test() {
try {
System.setIn(new FileInputStream("D:" + File.separator + "output.txt"));
byte[] buffer = new byte[1024];
int len = 0;
String str = "";
while ((len = System.in.read(buffer)) != -1) {
str += new String(buffer, 0, len);
}
System.out.println(str);
} catch (IOException e) {
e.printStackTrace();
}
}

7.5 输出内容

将内容输出到控制台和文件:

java
1
2
3
4
5
6
7
8
9
public void test() {
try {
System.out.println("这是输出到控制台的文字。");
System.setOut(new PrintStream("D:" + File.separator + "input.txt"));
System.out.println("这是输出到文件里的文字。");
} catch (IOException e) {
e.printStackTrace();
}
}

8 对象流

对象流主要有:ObjectInputStream、ObjectOutputStream。

这两个类型都是字节流,可以处理所有文件,可以将内存中的对象保存到本地,也可以将本地的对象还原到内存中。

8.1 序列化

8.1.1 概念

对象序列化机制允许把内存中的对象转换成平台无关的二进制流,当其它程序获取了这种二进制流,就可以恢复成原来的对象。

如果想将一个对象进行网络传输,要求是该对象必须是可序列化的,该类必须实现Serializable接口或者Externalizable接口。

不能序列化static和transient修饰的属性。

8.1.2 好处

序列化的好处在于可将任何实现了Serializable接口的对象转化为字节数据,使其在保存和传输时可被还原。

序列化是远程方法调用(Remote Method Invoke)过程的参数和返回值都必须实现的机制,而RMI是系统调用的基础,因此序列化机制是系统调用的基础。

8.1.3 实现

序列化是用ObjectOutputStream类保存基本类型数据或对象的机制,因为是输出到文件里,所以是输出流。

反序列化是用ObjectInputStream类读取基本类型数据或对象的机制,因为将数据输入到内存里,所以是输入流。

8.1.4 自定义

在进行序列化和反序列化时,虚拟机会首先试图调用对象里的writeObject和readObject方法,进行用户自定义的序列化和反序列化。

如果没有这样的方法,那么默认调用的是ObjectOutputStream的defaultWriteObject以及ObjectInputStream的defaultReadObject方法。

8.1.5 验证版本

序列化机制是通过判断类的serialVersionUID来验证版本一致性的。

在进行反序列化时,JVM会把传来的字节流中的serialVersionUID与本地相应实体类的serialVersionUID进行比较,如果相同就认为是一致的,可以进行反序列化,否则就会出现InvalidCastException序列化版本不一致的异常。

serialVersionUID有两种生成方式:生成默认的1L,或者生成一个64位的Hash字段。

8.2 ObjectInputStream

构造方法:

java
1
ObjectInputStream(InputStream in);

常用方法:

java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 从输入流中读入一个字节
int read();
// 从输入流中读入到数组
int read(byte[] buf);
// 从输入流中将len个数据读入到数组
int read(byte[] buf, int off, int len);
// 使用UTF-8编码读取字符串
String readUTF();
// 读取要保存的变量
Object readObject();
// 默认的读取变量的方法
void defaultReadObject();
// 关闭输入流并释放系统资源
void close();

示例:

java
1
2
3
4
5
6
7
8
9
10
11
public void deserialize() {
try {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("D:" + File.separator + "object.obj"));
System.out.println(ois.readInt());
System.out.println(ois.readObject());
System.out.println((Box) ois.readObject());
ois.close();
} catch (IOException e) {
e.printStackTrace();
}
}

8.3 ObjectOutputStream

构造方法:

java
1
DataOutputStream(OutputStream out);

常用方法:

java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 从指定字节中写出到输出流
void write(int b);
// 从数组中写出到输出流
void write(byte[] b);
// 从数组中将len个数据写出到输出流
void write(byte[] b, int off, int len);
// 使用UTF-8编码写入字符串
void writeUTF(String str);
// 写入要保存的变量
void writeObject(Object obj);
// 默认的写入变量的方法
void defaultWriteObject();
// 刷新该流的缓冲
void flush();
// 关闭输出流并释放系统资源
void close();

示例:

java
1
2
3
4
5
6
7
8
9
10
11
public void serialize() {
try {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("D:" + File.separator + "object.obj"));
oos.writeInt(100);
oos.writeObject("String");
oos.writeObject(new Box("box", 6, 8));
oos.close();
} catch (IOException e) {
e.printStackTrace();
}
}

9 随机存取文件流

随机存取文件流可以处理所有文件,既可以充当输入流,又可以充当输出流。

如果将要输出文件不存在则尝试自动创建,并将内容输出到此文件中。如果将要输出的文件存在,则将对文件内容进行覆盖。

9.1 RandomAccessFile

构造方法:

java
1
2
RandomAccessFile(File file, String mode);
RandomAccessFile(String name, String mode);

使用mode指定文件的访问模式:

  • r:以只读方式打开。
  • rw:打开以便读取和写入。
  • rws:还要求对文件的内容或元数据的更新都同步到底层存储设备。
  • rwd:还要求对文件内容的更新都同步到底层存储设备。

常用方法:

java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 从指定字节中写出到输出流
void write(byte[] b);
// 从数组中写出到输出流
void write(int b);
// 从数组中将len个数据写出到输出流
void write(byte[] b, int off, int len);
// 从输入流中读入一个字节
int read();
// 从输入流中读入到数组
int read(byte[] b);
// 从输入流中将len个数据读入到数组
int read(byte[] b, int off, int len);
// 获取文件记录指针的当前位置
long getFilePointer();
// 将文件记录指针定位到pos位置
void seek(long pos);
// 关闭流并释放系统资源
void close();

9.2 复制文件

使用随机存取文件流复制文件:

java
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
public void test() {
RandomAccessFile r = null;
RandomAccessFile w = null;
try {
r = new RandomAccessFile(new File("D:" + File.separator + "read.txt"), "r");
w = new RandomAccessFile(new File("D:" + File.separator + "write.txt"), "rw");
byte[] buffer = new byte[1024];
int len = 0;
while ((len = r.read(buffer)) != -1) {
w.write(buffer, 0, len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (r != null) {
try {
r.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (w != null) {
try {
w.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

9.3 插入内容

使用随机存取文件流插入内容:

java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public void test() {
RandomAccessFile raf = null;
try {
raf = new RandomAccessFile("D:" + File.separator + "read.txt", "rw");
raf.seek(3);
byte[] buffer = new byte[1024];
int len = 0;
String str = "";
while ((len = raf.read(buffer)) != -1) {
str += new String(buffer, 0, len);
}
raf.seek(3);
raf.write("read".getBytes());
raf.write(str.getBytes());
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
raf.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}

评论