Java·IO流

File类

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
三种构造器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package demo10;

import org.junit.Test;

import java.io.File;

public class FileTest {
@Test
public void test1(){
File file = new File("D:\\hello.txt");
System.out.println(file);
File file2 = new File("D:\\java","jdk");
System.out.println(file2);
File file3 = new File(file2,"jre");
System.out.println(file3);
}
}

在这里插入图片描述

常用方法

在这里插入图片描述

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
package demo10;

import org.junit.Test;

import java.io.File;

public class FileTest {
@Test
public void test2(){
File file = new File("D:\\hello.txt");
File file2 = new File("hello.txt");
System.out.println(file.getName());
System.out.println(file.getAbsolutePath());
System.out.println(file.getParent());
System.out.println(file.getPath());
System.out.println(file.length());
System.out.println(file.lastModified());
System.out.println("========================");
System.out.println(file2.getName());
System.out.println(file2.getAbsolutePath());
System.out.println(file2.getParent());
System.out.println(file2.getPath());
System.out.println(file2.length());
System.out.println(file2.lastModified());
}
}

hello.txt
D:\hello.txt
D:
D:\hello.txt
12

1622378943689

hello.txt
D:\Idea WorkSpace\learn\hello.txt
null
hello.txt
12
1622380762330

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package demo10;

import org.junit.Test;

import java.io.File;

public class FileTest {
@Test
public void test2(){
File file = new File("D:\\Java");
String[] list = file.list();
for (String s : list){
System.out.println(s);
}
System.out.println("========================");
File[] listFiles = file.listFiles();
for (File f : listFiles){
System.out.println(f);
}
}
}

bin
conf
COPYRIGHT
include
jmods
legal
lib

release

D:\Java\bin
D:\Java\conf
D:\Java\COPYRIGHT
D:\Java\include
D:\Java\jmods
D:\Java\legal
D:\Java\lib
D:\Java\release

在这里插入图片描述

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package demo10;

import org.junit.Test;

import java.io.File;

public class FileTest {
@Test
public void test2(){
File file = new File("D:\\hello.txt");
System.out.println(file.isFile());
System.out.println(file.isDirectory());
System.out.println(file.exists());
System.out.println(file.canRead());
System.out.println(file.canWrite());
System.out.println(file.isHidden());

}
}

在这里插入图片描述
在这里插入图片描述

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package demo10;

import org.junit.Test;

import java.io.File;
import java.io.IOException;

public class FileTest {
@Test
public void test2() throws IOException {
File file = new File("hello.txt");
System.out.println(file.exists());
System.out.println(file.createNewFile());

}
}

在这里插入图片描述

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package demo10;

import org.junit.Test;

import java.io.File;
import java.io.IOException;

public class FileTest {
@Test
public void test2() throws IOException {
File file = new File("hi.txt");
if(!file.exists()){
file.createNewFile();
System.out.println("Created!");
}

}
}

在这里插入图片描述

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package demo10;

import org.junit.Test;

import java.io.File;
import java.io.IOException;

public class FileTest {
@Test
public void test2() throws IOException {
File file = new File("hi.txt");
if(!file.exists()){
file.createNewFile();
System.out.println("Created!");
}else{
file.delete();
System.out.println("Deleted!");
}

}
}

在这里插入图片描述

IO流原理及分类

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

非文本比如视频、图像适合字节流,文本适合字符流。
在这里插入图片描述

IO流体系

在这里插入图片描述
在这里插入图片描述

FileReader读入数据

空参read方法

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
package demo10;


import java.io.File;
import java.io.FileReader;
import java.io.IOException;

public class IOTest {
public static void main(String[] args) throws IOException {
//1.实例化File对象,指明要操作的文件
File file = new File("hello.txt");
//2.提供具体的流
FileReader fr = new FileReader(file);
//3.数据的读入
//read():返回读入的字符,如果达到文件末尾,返回-1
int data = fr.read();
System.out.println((char)data);
while (data != -1){
System.out.print((char)data);
data = fr.read();
}
//4.流的关闭操作
fr.close();
}
}

在这里插入图片描述
改进

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
package demo10;


import java.io.File;
import java.io.FileReader;
import java.io.IOException;

public class IOTest {
public static void main(String[] args) throws IOException {
FileReader fr = null;
//1.实例化File对象,指明要操作的文件
File file = new File("hello.txt");
try {
//2.提供具体的流
fr = new FileReader(file);
//3.数据的读入
//read():返回读入的字符,如果达到文件末尾,返回-1
int data;
while ((data = fr.read())!=-1){
System.out.print((char)data);
}

} catch (IOException e) {
e.printStackTrace();
} finally {
//4.流的关闭操作
fr.close();
}
}
}

使用read重载方法

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
package demo10;


import java.io.File;
import java.io.FileReader;
import java.io.IOException;

public class IOTest {
public static void main(String[] args) throws IOException {
FileReader fr = null;
//1.实例化File对象,指明要操作的文件
File file = new File("hello.txt");
try {
//2.提供具体的流
fr = new FileReader(file);
//3.数据的读入
char[] cbuf = new char[5];
int len;
while ((len = fr.read(cbuf)) != -1) {
for (int i = 0; i < len; i++) {
System.out.print(cbuf[i]);
}
}

} catch (IOException e) {
e.printStackTrace();
} finally {
//4.流的关闭操作
fr.close();
}
}
}

在这里插入图片描述
注意我们这里的循环里是i<len,我们下面把它改成i<cbuf.length
在这里插入图片描述
在这里插入图片描述
结果:
在这里插入图片描述
可以看到cbuf在每一次读取时被一个个覆盖,而不是清空重新赋值。
这里重载的reader方法的返回值是:
在这里插入图片描述
或者不用for循环,用String输出,也要注意char数组的长度问题:
在这里插入图片描述

FileWriter写出

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package demo10;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

public class IOTest {
public static void main(String[] args) throws IOException {
//1.提供File类对象,指明写出到的文件
File file = new File("Hello.txt");
//2.提供FileWriter对象,用于数据的写出
FileWriter fw = new FileWriter(file);
//3.写出的操作
fw.write("Hello World!");
fw.write("Hello Java!");
//4.流的关闭
fw.close();
}
}

在这里插入图片描述
加个换行
在这里插入图片描述
在这里插入图片描述
之前文件被覆盖了。
如果源文件存在,就覆盖,如果不存在,就创建然后写出。
如果不想覆盖,就在FileWriter构造器中添加个true。
在这里插入图片描述
可以看到该参数为append,既追加,默认为false,所以是覆盖。

字符流不能处理图片

不能使用字符流来处理字节数据!

处理文本

最好来说:
在这里插入图片描述

实现图片复制

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
package demo10;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class IOTest {
public static void main(String[] args) throws IOException {
File src = new File("1.png");
File dest = new File("2.png");

FileInputStream fis = new FileInputStream(src);
FileOutputStream fos = new FileOutputStream(dest);

byte[] buffer = new byte[5];
int len;
while ((len = fis.read(buffer))!=-1){
fos.write(buffer,0,len);
}

fis.close();
fos.close();
}
}

在这里插入图片描述
在这里插入图片描述

实现了图片复制。

指定路径下文件的复制

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
package demo10;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class IOTest {
public static void main(String[] args) throws IOException {
long start = System.currentTimeMillis();
copyFile("1.mp4","2.mp4");
long end = System.currentTimeMillis();
System.out.println((end - start)/1000.0);
}
public static void copyFile(String srcPath,String destPath) throws IOException {
File src = new File(srcPath);
File dest = new File(destPath);

FileInputStream fis = new FileInputStream(src);
FileOutputStream fos = new FileOutputStream(dest);

byte[] buffer = new byte[5];
int len;
while ((len = fis.read(buffer))!=-1){
fos.write(buffer,0,len);
}

fis.close();
fos.close();
}
}

7.635

复制一个21s的mp4文件花了7.635s。

将buffer数组改为100大小
在这里插入图片描述

0.607

缓冲流字节型实现非文本文件复制

作用:提高流的读取和写入的速度。
注意到缓冲流是处理流,也就是要作用到节点流,所以要先来一个节点流。

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
package demo10;

import java.io.*;

public class BufferTest {
public static void main(String[] args) throws IOException {
//1.造文件
File src = new File("1.png");
File dest = new File("2.png");
//2.造流
//2.1造节点流
FileInputStream fis = new FileInputStream(src);
FileOutputStream fos = new FileOutputStream(dest);
//2.2造处理流也就是缓冲流
BufferedInputStream bis = new BufferedInputStream(fis);
BufferedOutputStream bos = new BufferedOutputStream(fos);
//3.复制细节:读取和写入
byte[] b = new byte[1024];
int len;
while ((len = bis.read(b))!=-1){
bos.write(b,0,len);
}
//4.资源关闭 先关外面的也就是处理流,再关里面的也就是节点流
//其实关闭外层流,内层流自动就关了,所以没必要再写。
bis.close();
bos.close();
/*fis.close();
fos.close();*/

}
}


缓冲流与节点流速度对比

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
package demo10;

import java.io.*;

public class BufferTest {
public static void main(String[] args) throws IOException {
long start = System.currentTimeMillis();
//1.造文件
File src = new File("1.mp4");
File dest = new File("2.mp4");
//2.造流
//2.1造节点流
FileInputStream fis = new FileInputStream(src);
FileOutputStream fos = new FileOutputStream(dest);
//2.2造处理流也就是缓冲流
BufferedInputStream bis = new BufferedInputStream(fis);
BufferedOutputStream bos = new BufferedOutputStream(fos);
//3.复制细节:读取和写入
byte[] b = new byte[1024];
int len;
while ((len = bis.read(b))!=-1){
bos.write(b,0,len);
}
//4.资源关闭 先关外面的也就是处理流,再关里面的也就是节点流
//其实关闭外层流,内层流自动就关了,所以没必要再写。
bis.close();
bos.close();
long end = System.currentTimeMillis();
System.out.println(end - start);
/*fis.close();
fos.close();*/

}
}

24

而之前的节点流是0.607s也就是607ms,是将近30倍,这里我们用的都是1024大小的byte数组。

提高读写速度的原因:内部提供了一个缓冲区。

缓冲流对文本文件的复制

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package demo10;

import java.io.*;

public class BufferTest {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new FileReader(new File("hello.txt")));
BufferedWriter bw = new BufferedWriter(new FileWriter(new File("hi.txt")));

char[] c = new char[1024];
int len;
while ((len = br.read(c)) != -1){
bw.write(c,0,len);
}
br.close();
bw.close();

}
}

上述方式仍然使用char[]数组
方式二:使用String和BufferedReader里的readLine()方法。
在这里插入图片描述

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package demo10;

import java.io.*;

public class BufferTest {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new FileReader(new File("hello.txt")));
BufferedWriter bw = new BufferedWriter(new FileWriter(new File("hi.txt")));

String data;
while ((data = br.readLine()) != null){
bw.write(data);//data中不包含换行符
}
br.close();
bw.close();

}
}

在这里插入图片描述

在这里插入图片描述

所以这里要加一个换行符
在这里插入图片描述
或者调用newLine()方法
在这里插入图片描述

总结

在这里插入图片描述
此外,处理流中还有flush方法,调用它可以把缓冲区的内容写出去,只不过缓冲流自动调用它,所以在这里不用管

处理流之二 转换流

字节输入流转换为字符输入流

在这里插入图片描述
在这里插入图片描述

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
package demo10;

import java.io.*;
//InputStreamReader: 将一个字节的输入流转换为字符的输入流
//OutputStreamWriter: 将一个字符的输出流转换为字节的输出流
public class TransferTest {
public static void main(String[] args) throws IOException {
//字节流处理了一个txt
FileInputStream fis = new FileInputStream("hello.txt");
//将字节输入流转换为字符输入流

// InputStreamReader isr = new InputStreamReader(fis);
//使用UTF-8字符集
//具体使用哪个字符集 看txt保存的时候用的哪个
InputStreamReader isr = new InputStreamReader(fis,"UTF-8");
char[] c = new char[1024];
int len;
while ((len = isr.read(c))!=-1){
System.out.println(new String(c,0,len));
}
isr.close();

}
}

在这里插入图片描述
这里我们如果用gbk去解码,肯定不对,会出现乱码。

综合使用转换流

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package demo10;

import java.io.*;
//InputStreamReader: 将一个字节的输入流转换为字符的输入流
//OutputStreamWriter: 将一个字符的输出流转换为字节的输出流
public class TransferTest {
public static void main(String[] args) throws IOException {
File f1 = new File("hello.txt");
File f2 = new File("hello_gbk.txt");
FileInputStream fis = new FileInputStream(f1);
FileOutputStream fos = new FileOutputStream(f2);
InputStreamReader isr = new InputStreamReader(fis,"UTF-8");
OutputStreamWriter osw = new OutputStreamWriter(fos,"GBK");

char[] c = new char[1024];
int len;
while ((len = isr.read(c)) != -1){
osw.write(c,0,len);
}
isr.close();
osw.close();
}
}

在这里插入图片描述
我们字节流输入,被字节转字符包住,用字符数组接收,在用OutputStreamWriter字符转字节包住的字节流输出出去,并且输出为gbk编码字符集编码的文本。

字符集

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

标准输入输出流

在这里插入图片描述
在这里插入图片描述

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package demo10;

import java.io.*;

public class TransferTest {
public static void main(String[] args) throws IOException {
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader br = new BufferedReader(isr);
while (true){
System.out.print("请输入字符串:");
String data = br.readLine();
if ("e".equalsIgnoreCase(data)||"exit".equalsIgnoreCase(data)){
System.out.println("程序结束");
break;
}
String s = data.toUpperCase();
System.out.println(s);
}
br.close();
}
}

在这里插入图片描述
System.in是字节流,所以有些情况需要转换。

打印流

在这里插入图片描述

数据流

在这里插入图片描述

对象流

在这里插入图片描述
在这里插入图片描述

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
package demo10;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;

public class ObjectStream {
public static void main(String[] args) {
//序列化:将内存中的java对象保存到磁盘中或者通过网络传输出去
ObjectOutputStream oos = null;
try {
oos = new ObjectOutputStream(new FileOutputStream("object.txt"));
oos.writeObject(new String("I love java"));
oos.flush();

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

在这里插入图片描述
这个文件不是用来双击打开看的,就是把序列化的对象持久的保存在磁盘上。

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
package demo10;

import java.io.*;

public class ObjectStream {
public static void main(String[] args) {
ObjectInputStream ois = null;
try {
ois = new ObjectInputStream(new FileInputStream("object.txt"));

Object o = ois.readObject();

String str = (String) o;

System.out.println(str);
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} finally {
if(ois != null){
try {
ois.close();
} catch (IOException e) {
e.printStackTrace();
}
}

}



}

}

在这里插入图片描述
这个操作就反序列化了,将磁盘文件中的对象还原为内存中的java对象。

自定义类实现序列化和反序列化

标识接口 Serializable

在这里插入图片描述
在这里插入图片描述

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
package demo10;

import java.io.Serializable;

public class Person implements Serializable {

public static final long serialVersionUID = 475463534532L;

private String name;
private int age;

public Person(String name, int age) {
this.name = name;
this.age = age;
}

public void setName(String name) {
this.name = name;
}

public void setAge(int age) {
this.age = age;
}

public String getName() {
return name;
}

public int getAge() {
return age;
}

@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}

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
45
46
47
48
49
50
51
52
53
54
55
package demo10;

import java.io.*;

public class ObjectStream {
public static void main(String[] args) {

ObjectOutputStream oos = null;
try {
oos = new ObjectOutputStream(new FileOutputStream("object.txt"));
oos.writeObject(new String("I love java"));
oos.flush();

oos.writeObject(new Person("Hawkeye",20));
oos.flush();

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

ObjectInputStream ois = null;
try {
ois = new ObjectInputStream(new FileInputStream("object.txt"));

Object o = ois.readObject();

String str = (String) o;
Person p = (Person) ois.readObject();

System.out.println(str);
System.out.println(p);
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} finally {
if(ois != null){
try {
ois.close();
} catch (IOException e) {
e.printStackTrace();
}
}

}
}
}

在这里插入图片描述

serialVersionUID的理解

在这里插入图片描述
如果我们对一个带UID的Person类序列化,那么进行一些操作比如添加一个属性id,重写toString,反序列化读回来的仍然是那个Person而且id为默认值0,如果我们对一个不带UID的Person类序列化,再执行上述操作,会报异常。
在这里插入图片描述
简而言之:一个对象,作为序列化的二进制流,如果没有UID,它的类改变了,就还原不回来了。

其他要求

在这里插入图片描述

所有属性都需要可序列化

transient关键字

我们都知道一个对象只要实现了Serilizable接口,这个对象就可以被序列化,java的这种序列化模式为开发者提供了很多便利,我们可以不必关系具体序列化的过程,只要这个类实现了Serilizable接口,这个类的所有属性和方法都会自动序列化 。然而在实际开发过程中,我们常常会遇到这样的问题,这个类的有些属性需要序列化,而其他属性不需要被序列化,打个比方,如果一个用户有一些敏感信息(如密码,银行卡号等),为了安全起见,不希望在网络操作(主要涉及到序列化操作,本地序列化缓存也适用)中被传输,这些信息对应的变量就可以加上transient关键字。换句话说,这个字段的生命周期仅存于调用者的内存中而不会写到磁盘里持久化。
总之,java 的transient关键字为我们提供了便利,你只需要实现Serilizable接口,将不需要序列化的属性前添加关键字transient,序列化对象的时候,这个属性就不会序列化到指定的目的地中。
在这里插入图片描述

static修饰的属性不能被序列化

随机存取文件流

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

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
package demo10;

import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;

public class RandomTest {
public static void main(String[] args) {
//
RandomAccessFile raf = null;
RandomAccessFile raf2 = null;
try {
raf = new RandomAccessFile(new File("1.png"), "r");
raf2 = new RandomAccessFile(new File("11.png"), "rw");

byte[] buffer = new byte[1024];
int len;
while ((len = raf.read(buffer)) != -1) {
raf2.write(buffer, 0, len);
}

} catch (IOException e) {
e.printStackTrace();
} finally {
if (raf != null && raf2 != null) {
try {
raf.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
raf2.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}

在这里插入图片描述
发现可以完成文件的复制。
下面我们新建一个1.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
package demo10;

import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;

public class RandomTest {
public static void main(String[] args) {

RandomAccessFile raf = null;

try {

raf = new RandomAccessFile(new File("1.txt"), "rw");

raf.write("xyz".getBytes());

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

在这里插入图片描述
结果如果本文件存在,则不是对文件直接覆盖,而是从源文件开头一个个覆盖,这里表现为xyz覆盖abc,按内容长度覆盖。
在这里插入图片描述

RandomAccessFile实现对数据插入

seek方法

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
package demo10;

import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;

public class RandomTest {
public static void main(String[] args) {

RandomAccessFile raf = null;

try {

raf = new RandomAccessFile(new File("1.txt"), "rw");
//将指针调到角标为3的位置
raf.seek(3);
raf.write("xyz".getBytes());

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

在这里插入图片描述
从3开始往后覆盖。

下面实现插入
更改1.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
43
44
package demo10;

import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;

public class RandomTest {
public static void main(String[] args) {

RandomAccessFile raf = null;

try {

raf = new RandomAccessFile(new File("1.txt"), "rw");
//将指针调到角标为3的位置
raf.seek(3);
//减少stringbuilder底层char数组扩容
StringBuilder sb = new StringBuilder((int) new File("1.txt").length());
//保存指针3后面的所有数据到sb中
byte[] buffer = new byte[20];
int len;
while ((len = raf.read(buffer))!=-1){
sb.append(new String(buffer,0,len));
}
//此时指针在最后,需要调回来
raf.seek(3);
raf.write("xyz".getBytes());
//写出去之后指针自动在z后面,再写sb中内容
raf.write(sb.toString().getBytes());

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

实现了从第三个插入xyz
在这里插入图片描述


Java·IO流
http://example.com/2021/06/01/Java%C2%B7IO%E6%B5%81%C2%B7%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%88%E4%B8%80%EF%BC%89/
作者
AHawkeye
发布于
2021年6月1日
许可协议