0%

java | IO 基础

  • 字节流
    • 流中的数据的最小单位是字节
  • 字符流
    • 流中的数据的最小单位是字符

字节流

要理解流的含义,当建立管道和文件连通后。你每次读取,都是文件的下一个流字节,就好像管道里的水一样。

输入流

单字节读取

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

import lombok.extern.slf4j.Slf4j;

import java.io.*;

@Slf4j(topic = "c.Test")
public class Run {
public static void main(String[] args) throws IOException {
// 创建文件对象
File file = new File("src/main/resources/words");
//创建一个字节输入流管道与源文件接通
InputStream inputStream = new FileInputStream(file);
//读取一个字节的编号返回,读取完返回 -1
// inputStream.read() 读的是字节编号,需要转化为 char
System.out.println((char) inputStream.read());
System.out.println((char) inputStream.read());
System.out.println((char) inputStream.read());
}

}

inputStream.read() 一个字节一个字节的读。

中文字符占据 3 个字节,如果用上面方法读的话,会出现乱码。

字节数组读取

字节数组读取。这个字节数组相当于桶。假设文件内容为

1234567
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 com.redisc;

import lombok.extern.slf4j.Slf4j;

import java.io.*;

@Slf4j(topic = "c.Test")
public class Run {
public static void main(String[] args) throws IOException {
// 创建文件对象
File file = new File("src/main/resources/words");
//创建一个字节输入流管道与源文件接通
InputStream inputStream = new FileInputStream(file);
//定义一个字节数组读取数据
byte[] buffer = new byte[3];
int len = inputStream.read(buffer);
System.out.println(new String(buffer));

len = inputStream.read(buffer);
System.out.println(new String(buffer));

len = inputStream.read(buffer);
System.out.println(new String(buffer));
}

}

那么输出为

1
2
3
123
456
756

由于最后的输出字节流,只有一个 7,只能替换原来桶中的 4.

所以,这个默认机制可能会导致程序 BUG,使用的时候,应该用

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 com.redisc;

import lombok.extern.slf4j.Slf4j;

import java.io.*;

@Slf4j(topic = "c.Test")
public class Run {
public static void main(String[] args) throws IOException {
// 创建文件对象
File file = new File("src/main/resources/words");
//创建一个字节输入流管道与源文件接通
InputStream inputStream = new FileInputStream(file);
//定义一个字节数组读取数据
byte[] buffer = new byte[3];
int len = inputStream.read(buffer);
System.out.println(new String(buffer, 0, len));

len = inputStream.read(buffer);
System.out.println(new String(buffer, 0, len));

len = inputStream.read(buffer);
System.out.println(new String(buffer, 0, len));
}

}

输出流

把内存中的数据写到磁盘上。

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 com.redisc;

import lombok.extern.slf4j.Slf4j;

import java.io.*;

@Slf4j(topic = "c.Test")
public class Run {
public static void main(String[] args) throws IOException {
// 创建一个文件对象(写数据到文件,文件会自动创建)
File file = new File("src/main/resources/1.txt");
OutputStream os = new FileOutputStream(file);
// 写字节
os.write(97);
byte[] bytes = new byte[]{97, 98, 99};
os.write(bytes);
byte[] bytes1 = "12345".getBytes();
os.write(bytes1);
//刷新数据
os.flush();
os.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
package com.redisc;

import lombok.extern.slf4j.Slf4j;

import java.io.*;

@Slf4j(topic = "c.Test")
public class Run {
public static void main(String[] args) throws IOException {
InputStream is = null;
OutputStream outputStream = null;
try {
is = new FileInputStream("");
outputStream = new FileOutputStream("");

byte[] buffer = new byte[1024];
int len;
while ((len = is.read(buffer)) != -1) {
outputStream.write(buffer, 0, len);
}
} catch (Exception e) {
e.printStackTrace();
}finally {
if(is != null) is.close();
if(outputStream != null) outputStream.close();
}
}

}

字符流

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

import lombok.extern.slf4j.Slf4j;

import java.io.*;

@Slf4j(topic = "c.Test")
public class Run {
public static void main(String[] args) throws IOException {
Reader fr = new FileReader("src/main/resources/words");
// 按照字符读取,每次读取一个字符的编号返回
int code = fr.read();
System.out.println((char) code);
int code1 = fr.read();
System.out.println((char) code1);
int code2 = fr.read();
System.out.println((char) code2);
}

}

writer 类似,可以自己查找相关使用。

请我喝杯咖啡吧~