深入总结Java的IO流
- 【前言】此文章为总结性文章,适合同仁们觉得基础薄弱时看一看,也是对自己基础的一个总结。
(一).输入输出流
按流的分类可以把IO流分为输入输出流,千万注意,这里的输入输出是按照运行程序所在内存的角度划分.比如:1.数据从内存到硬盘,则为输出流。2.数据从服务器server—>客户端client,对于server来说是输出流,对于client来说从网络往内存输入数据则为输入流。
(二).字节流和字符流
【预备知识】字节(byte):字节是通过网络传输信息(或在硬盘或内存中存储信息)的单位。字节是计算机信息技术用于计量存储容量和传输容量的一种计量单位,1个字节等于8位二进制,它是一个8位的二进制数,是一个很具体的存储空间。1字节=8位(1byte = 8bit)。字符:人们使用的记号,抽象意义上的一个符号。 ‘1’, ‘中’, ‘a’, ‘$’, ‘¥’, ……按照ANSI编码标准,标点符号、数字、大小写字母都占一个字节,汉字占2个字节。按照UNICODE标准所有字符都占2个字节。
- 总结:1 byte = 8bit;1 char = 2 byte。
(A).IO流大致分为俩种:
(1)字节流:对应抽象类为InputStream(输入流)和 OutputStream(输出流)。
(2)字符流:对应抽象类为Reader(输入流)和Writer(输出流)。
(B).抽象类的具体实现:
(1)字节流:(常用的)FileInputStream实现了InputStream。(常用的)FileOutputStream实现了OutputStream。
(2)字符流:(常用的)BufferedReader、InputStreamReader、 StringReader实现了Reader,FileReader继承了InputStreamReader。(常用的)BufferedWriter、OutputStreamWriter、StringWriter实现了Writer,FileWriter继承了OutputStreamWriter。
- 使用FileInputStream来执行输入,FileOutputStream来执行输出,实现拷贝文件功能。
@Test
public void copyFile(String oldPath, String newPath) {
try {
int byteread = 0;
File oldfile = new File(oldPath);
if (oldfile.exists()) { //文件存在时
FileInputStream inStream = new FileInputStream(oldPath); //读入原文件
FileOutputStream fs = new FileOutputStream(newPath);
byte[] buffer = new byte[100];
while ((byteread = inStream.read(buffer)) >0) {
fs.write(buffer, 0, byteread);
}
inStream.close();
fs.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
(三).输入输出流体系
- 图中,4个缓冲流BufferedInputStream,BufferOutputStream,BufferReader,BufferWriter增加了缓冲功能,提高了输入输出效率,增加缓冲功能后需要使用flush()才可以将缓冲区的内容写入实际的物理结点。
- PipedInputStream,PipedOutputStream等用于实现进程间通信。
- 下面我们来看看如何使用:
public class TestStream {
// 读取文件中字符
@Test
public void testRead() throws IOException {
String path = "read.txt";
FileReader read = new FileReader(path);
BufferedReader reader = new BufferedReader(read);
while (reader.readLine() != null) {
String s = reader.readLine();
System.err.println(s);
}
reader.close();
}
// 写入字符到文件
@Test
public void testWrite() throws IOException {
String path = "write.txt";
FileWriter write = new FileWriter(path);
BufferedWriter writer = new BufferedWriter(write);
char[] buffer = new char[1024];
for (int i = 0; i < 1024; i++) {
if ((char) 'a' + i > Character.MAX_VALUE) {
buffer[i] = 'z';
System.err.println(1);
} else {
buffer[i] = (char) ('a' + i);
}
}
writer.write(buffer);
writer.close();
}
// 删除文件内容
@Test
public void testDelete() throws IOException {
String path = "write.txt";
FileWriter write = new FileWriter(path);
BufferedWriter writer = new BufferedWriter(write);
StringBuffer buffer = new StringBuffer();
writer.write(buffer.toString());
writer.close();
}
// 替换内容
@Test
public void testDeleteAndReplace() throws IOException {
String path = "write.txt";
FileWriter write = new FileWriter(path);
BufferedWriter writer = new BufferedWriter(write);
int i = 0;
while (++i < 100) {
StringBuffer buffer = new StringBuffer();
buffer.append(Math.random());
writer.write(buffer.toString() + "\r\n");
}
writer.close();
}
(四).处理流
- 处理流可以隐藏底层设备上节点流的差异,并且对外提供更加方便的输入输出方法。识别处理处理流非常简单,只要流的构造参数不是一个物理节点,而是已经存在的流,那么此流一定是物理流。
FileOutputStream fos = new FileOutputStream("test.txt");
PrintStream ps = new PrintStream(fos);
InputStreamReader reader = new InputStreamReader(System.in);
BufferReader br = new BufferReader(reader);
(五).转换流
- InputStreamReader将字节输入流转换为字符输入流,OutputStreamWriter将字节输出流转换为字符输出流。【注意】细心的人可以发现只有字节转换为字符,那是因为字符流用起来更加方便,字节流用的更加广泛,所以我们一般把字节流转换为字符流。
try{
InputStreamReader reader = new InputStreamReader(System.in);
BufferReader br = new BufferReader(reader);
String line = null;
//逐行读取字符输入流
while((line = br.readLine())!=null){
if(line.equals("exit")){
System.exit(1);
}
}
System.out.println("输入的内容为:"+line);
}
catch(IOException ioe){
ioe.printStackTrace();
}