Java I/O体系(一)
I/O(输入输出)对于哪一种编程语言来说,都是很重要的,对于我们学的Java也一样。I/O也是网络通信、文件读写的基础;既然它这么重要,当然要好好认识一下它咯。
1. I/O类图
这张图一看,懵了,涉及的类太多了,其实呢,平时常用的类并没有那么多,这里只是全部展示出来,而且,这里面涉及的类大多数都是一对儿一对儿出现的,用法也基本类似;所以只要记住几个关键类的用法就好了。接着我们就来学习一些比较常用的类吧!
2. I/O流的分类
既然要分类,就要有分类依据
1) 根据处理数据类型的不同分为:字符流和字节流
a) 字符流,字面理解就是一个字符一个字符的操作,由于数据编码的不同,于是就有了对字符进行高效操作的流对象;本质上来说,就是基于字节流读取时,去查了指定的字符编码表(比如什么GBK、GB2312等等)。
b) 字节流,也就是一个字节一个字节的操作,以一个字节(8位二进制)为单位。
这两者的区别主要在于读写单位的不同和处理的对象不同:字节流以字节(8bit)为单位,字符流以字符为单位,根据码表映射字符,一次可能读多个字节;字节流能处理所有类型的数据(如图片、视频等),而字符流只能处理字符类型的数据。
2) 根据数据流向不同分为:输入流和输出流
对输入流只能进行读操作,对输出流只能进行写操作,程序中需要根据待传输数据的不同特性而使用不同的流。
知道了大概的分类,就可以进一步了解Java I/O的类了,一起来看看:
3. Java I/O对象(InputStream、OutputStream类)
1) 输入字节流InputStream
从刚开始的类图可以看出来,InputStream是所有输入字节流的父类而且它是一个抽象类,经常会用到的它的子类有:
a) ByteArrayInputStream(字节数组输入流)
它可以用来读取一些二进制文件
b) FileInputStream(文件输入流)
这个类就厉害了,经常用来读取磁盘上的文件(稍后会举例哦)
c) PipedInputStream(管道输入流)
这是从与其它线程共用的管道中读取数据
下面我们来举一个简单的例子:
package learn.io;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
public class InputSteamTest {
public static void main(String args[]) {
/*创建文件对象*/
File file = new File("f:\\input.txt");
try {
/*创建文件输入流*/
InputStream inputStream = new FileInputStream(file);
/*创建字节数组缓冲*/
byte[] b = new byte[inputStream.available()];
/*读取*/
inputStream.read(b);
/*打印输出*/
System.out.println(new String(b));
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
这样我们就可以读取到文件里面的内容了(当然这个例子并不完善),还有很多的类暂不一一举例。
2) 输出字节流OutputStream
a) OutputStream 是所有的输出字节流的父类,它是一个抽象类。
b) ByteArrayOutputStream、FileOutputStream 是两种基本的介质流,它们分别向Byte数组、和本地文件中写入数据。PipedOutputStream 是向与其它线程共用的管道中写入数据,
c) ObjectOutputStream和所有FilterOutputStream 的子类都是装饰流。
综合上面的例子,这里来一个输入输出结合使用的例子
package learn.io;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class InputSteamTest {
public static void main(String args[]) {
/* 创建文件对象 */
File inFile = new File("f:\\input.txt");
File outFile = new File("f:\\output.txt");
try {
/* 创建文件输入流 */
InputStream inputStream = new FileInputStream(inFile);
OutputStream outputStream = new FileOutputStream(outFile);
/* 创建字节数组缓冲 */
byte[] inByte = new byte[1024];
int length = 0;
/*循环读取写入*/
while ((length = inputStream.read(inByte)) != -1) {
outputStream.write(inByte, 0, length);
}
/*关闭流*/
inputStream.close();
outputStream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
I/O的学习要多查看文档,有的类的使用方法看一下文档就会使用了。
4. 字符输入流Reader
在上面的继承关系图中可以看出:
1) Reader 是所有的输入字符流的父类,它是一个抽象类。
2) CharReader、StringReader 是两种基本的介质流,它们分别将Char 数组、String中读取数据。PipedReader是从与其它线程共用的管道中读取数据。
3) BufferedReader 很明显就是一个装饰器,它和其子类负责装饰其它Reader 对象。
4) FilterReader 是所有自定义具体装饰流的父类,其子类PushbackReader对Reader 对象进行装饰,会增加一个行号。
5) InputStreamReader 是一个连接字节流和字符流的桥梁,它将字节流转变为字符流。FileReader 可以说是一个达到此功能、常用的工具类,在其源代码中明显使用了将FileInputStream转变为Reader 的方法。我们可以从这个类中得到一定的技巧。Reader中各个类的用途和使用方法基本和InputStream 中的类使用一致。后面会有Reader 与InputStream 的对应关系。
下面再举个简单的例子:
package learn.io;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class StringReaderTest {
public static void main(String args[]) {
/* 使用BufferedReader封装系统标准输入流 */
BufferedReader bufferedReader = new BufferedReader(
newInputStreamReader(System.in));
try {
/* 读取一行数据 */
String text = bufferedReader.readLine();
/* 打印出输入的数据 */
System.out.println("你输入的是:" + text);
bufferedReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
这个例子,会将System.in这个系统标准输入流(对应的其实就是键盘)中的数据打印出来,也是我们经常会用的输入数据的方式。
5. 字符输出流Writer
和Reader类一样的道理,Writer类是所有的输出字符流的父类,也是一个抽象类,使用时也是用到它的子类,常用的有这些:
1) CharArrayWriter、StringWriter是两种基本的介质流,它们分别向Char 数组、String 中写入数据。PipedWriter 是向与其它线程共用的管道中写入数据,
2) BufferedWriter 是一个装饰器为Writer提供缓冲功能。
3) PrintWriter 和PrintStream 极其类似,功能和使用也非常相似。
4) OutputStreamWriter 是OutputStream到Writer 转换的桥梁,它的子类FileWriter 其实就是一个实现此功能的具体类
例子:
package learn.io;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
public class StringWriter {
public static void main(String args[]) {
/* 使用BufferedReader封装系统标准输入流 */
BufferedReader bufferedReader = new BufferedReader(
newInputStreamReader(System.in));
File file=new File("f:\\output.txt");
try {
/* 读取一行数据 */
String text = bufferedReader.readLine();
/* 打印出输入的数据 */
System.out.println("你输入的是:" + text);
FileWriter fileWriter=new FileWriter(file);
fileWriter.write(text);
System.out.println("你输入的字符已保存到 " + file.getAbsolutePath());
fileWriter.close();
bufferedReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
还有很多I/O类学完,下一篇继续哦