King's Studio

Java IO总结

字数统计: 1.5k阅读时长: 6 min
2019/01/30 Share

IO部分学习了一段时间了,现在来做个初步的总结。我的侧重点主要在IO流部分,主要分为两块:节点流和处理流。节点流就是离数据最近的流,处理流则是用于提高性能增强功能,我们首先来看节点流。

节点流

节点流根据处理的数据类型又可分为两部分,字节流和字符流。字节流可以处理一切文件如纯文本、音频、视频等,而字符流只能处理纯文本文件。

字节流

不论是字节流还是字符流,根据数据流向不同,都可划分成输入流和输出流,输入字节流InputStream,输出字节流OutputStream。InputStream是所有的输入字节流的父类,OutputStream是所有的输出字节流的父类,我们通过字节流读取文件的例子来进行理解。

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 ReadFileTest {
//读取文件
public static void main(String[] args) {
//1、建立联系
File src = new File("/Users/jinqi/Desktop/a.txt");
//2、选择流
InputStream is = null;//设置is为全局变量
try {
//字节缓冲流,提高性能
is = new BufferedInputStream(new FileInputStream(src));
//3、操作:创建数组接收读取内容
byte[] car = new byte[10];
int len = 0;
//循环读取,因为怕一次读取不完整个文件
while(-1!=(len = is.read(car))) {//-1表示数据读取结束,read()方法中传输接收的数组
//输出:字节数组转换成字符串
String info = new String(car,0,len);//从第0个开始,读取len长度的文件
System.out.println(info);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
System.out.println("文件不存在");
}catch (IOException e) {
e.printStackTrace();
System.out.println("读取文件失败");
}finally {//释放资源
if (null!=is) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
System.out.println("关闭文件输入流失败");
}
}
}
}
}

字节流写出文件和读取文件步骤基本相同,要注意的是写出文件中需要加入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
26
27
28
29
30
31
32
33
public class WriteFileTest {

public static void main(String[] args) {
//1、建立联系:新建File对象
File dest = new File("/Users/jinqi/Desktop/b.txt");
//2、选择流:文件输出流
OutputStream os = null;//os设置为全局变量
try {
//字节缓冲流,提高性能
os = new BufferedOutputStream(new FileOutputStream(dest,true));//true表示每次运行程序都是叠加,false表示每次运行是覆盖
//3、操作:编辑写出的内容
String str = "coding to change the world \r\n";
//因为write()方法需要传进去的都是byte数组,在这里需要把字符串转换成字节数组
byte[] data = str.getBytes();
os.write(data,0,data.length);
//强制刷新(规范操作)
os.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
System.out.println("文件未找到");
}catch (IOException e) {
e.printStackTrace();
System.out.println("文件写出失败");
}finally {
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
System.out.println("文件写出流关闭失败");
}
}
}
}

文件与文件夹的字符流拷贝前面已经写过,见上一篇《手写字节流文件拷贝类》,这里就不再重复列出。

字符流

字符流只能对纯文本进行操作,因此文件拷贝我们用字节流写过之后,就不再用字符流处理,同样,字符流也可分为输入和输出流,输入字符流Reader,输出字符流Writer,Reader是所有的输入字符流的父类,Writer是所有的输出字符流的父类,我们下面通过字符流读取纯文本的例子进行理解。

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
public class ReaderTest {    
public static void main(String[] args) {
//1、建立源
File src = new File("/Users/jinqi/Desktop/test/a.txt");
//2、选择流
Reader reader = null;
try {
//字符缓冲流,提高性能
reader = new BufferedReader(new FileReader(src));
//3、读取操作
char[] flush = new char[1024];
int len = 0;
while(-1!=(len = (reader.read(flush)))) {
//因为读取到的是字符数组,所以要把字符数组转换为字符串
String str = new String(flush, 0, len);
//打印字符串
System.out.println(str);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
System.out.println("文件不存在");
} catch (IOException e) {
e.printStackTrace();
System.out.println("文件读取失败");
}finally {
if (null!= reader) {
try {
//4、关闭资源
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}

字符流文件写出同样和文件读取步骤相同,一样需要添加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
26
27
28
29
public class Writer {
public static void main(String[] args) {
//1、建立源
File dest = new File("/Users/jinqi/Desktop/test/d.txt");
//2、选择流
BufferedWriter wr = null;
try {
//默认为true,是追加文件,而不是覆盖
wr = new BufferedWriter(new FileWriter(dest,true));//字符缓冲流,提高性能
//3、写出操作
String msg = "南京\r\n香港\r\n澳门\r\n";
//方式一
wr.write(msg);
//方式二
wr.append("我都想去");
wr.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
}catch (IOException e) {
e.printStackTrace();
}finally {
try {
wr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

处理流

看完了节点流,我们来看看处理流,处理流分为转换流、缓冲流、打印流等,我们这里主要研究转换流。

转换流

同样,转换流根据数据的流向也可分为输入和输出流,输入流InputStreamReader,输出流OutputStreamWriter,InputStreamReader用于解码,OutputStreamWriter用于编码,我们通过下面的例子进行理解。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class InputStreamReader {

public static void main(String[] args) throws IOException,UnsupportedEncodingException, FileNotFoundException {
//指定解码字符集
BufferedReader br = new BufferedReader(
new java.io.InputStreamReader(
new FileInputStream(
new File("/Users/jinqi/Downloads/JavaDevelopStudy/ReStudy/codingTest/coding.java")), "utf-8")
);
String info = null;
while(null!=(info=br.readLine())) {
System.out.println(info);
}
br.close();
}
}

转换流使用注意点,编码字符集和解码字符集必须统一,解码字符集设置要看源文件的编码字符集,解决乱码的主要方法就在于此。

缓冲流

缓冲流的使用在于提高性能,在每次读取写出的时候都可在外层套上缓冲流,同样根据数据流向,也能分为输入流和输出流,这里不再做详细介绍。

注意问题

以下流的新增方法使用时不能发生多态:ByteArrayOutputStream、BufferedReader、BufferedWriter、DataInputStream、DataOutputStream、ObjectInputStream、ObjectOutputStream、PrintStream。

原文作者:金奇

原文链接:https://www.rossontheway.com/2019/01/30/java回顾6/

发表日期:January 30th 2019, 12:00:00 am

更新日期:March 21st 2019, 9:34:13 am

版权声明:本文采用知识共享署名-非商业性使用 4.0 国际许可协议进行许可,除特别声明外,转载请注明出处!

CATALOG
  1. 1. 节点流
    1. 1.1. 字节流
    2. 1.2. 字符流
  2. 2. 处理流
    1. 2.1. 转换流
    2. 2.2. 缓冲流
  3. 3. 注意问题