Java IO流的那些爱恨情仇

        又开始回头重新补Java基础了,以前也是去网上直接下代码,这样导致自己只会用,对Java IO流内部机制并不熟悉,实实在在的一个代码搬运工。痛定思痛,觉得自己不能这么干了。基础最为重要,回头重新研究。好了,废话不多说,开扯。一开始我也是只是去网上搜搜看看别人怎么讲。哎,听的糊里糊涂的,不过看的多了,也就慢慢懂了一些。现在就把我理解的总结下。

1.字节流

1)输入字节流 InputStream

基本方法:

InputStream in = new InputStream(file) / /file是文件名
 int b  = in.read();      读取一个byte无符号填充到int底八位,-1是EOF
 int.read(byte[] buf)    读取数据填充到buf中
 int.read(byte[] buf,int start,int size)  读取数据填充到buf中
 in.close      关闭输入流

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

public class FileInputStream_Test {

	public static void main(String[] args) throws IOException {
		
		//方式一
		InputStream in =new FileInputStream("D:/test.txt");
		byte b[] = new byte[in.available()];
		in.read(b);					//直接把所有字节读入byte数组
		System.out.println(new String(b));		//要把byte数组打印出来得转成String
		
		//方式二
		File file = new File("D:/test.txt");
		InputStream is =new FileInputStream(file);  //这是FileInputStream另一种实例化方式
		int a;
		while((a=is.read())!=-1){		    //这是一个个读取,每一次read都是读一个字节
			System.out.print((char)a);
		}
		
	}
}

注意,如果test.txt里有中文,方式二是会乱码的,因为 is.read() 每一次是读一个字节,但是一个汉字是两个字节(得看本地编码GBK下两个字节,UTF-8下3个字节),它一下只读一个字节就相当于读了半个汉字,那打印出来必定是乱码,哈哈,一个字母是一个字节,所以换成字母打印正常。

2)输出字节流 OutputStream

这个是所有输出字节流的父类。

基本方法:

OutputStream out = new OutputStream(file) / /file是文件名
 out.write(int b)     写出一个byte 到流 b 的底八位写出
 out.write(byte[] buf)    将buf的一部分写入流中
 out.write(byte[] buf, int start, int size)  将buf的一部分写入流中
 out.flush()      清理缓存
 out.close

package IO;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public class FileOutputStream_Test {

	public static void main(String[] args) throws IOException {
		
		//方式一
		InputStream is =new FileInputStream("D:/test.txt");//先从一个文件里读些数据
		byte b[] = new byte[is.available()];
		is.read(b);	
		OutputStream os = new FileOutputStream("D:/test1.txt"); //实例化一个输出流,如果文件不存在会自动创建
		os.write(b);//直接把一个byte数组写入到文件中
	
		//方式二
		InputStream is1 =new FileInputStream("D:/test.txt");
		OutputStream os1 = new FileOutputStream("D:/test1.txt");
		int a;
		while((a=is1.read())!=-1){		//读一个字节,写一个字节
			os1.write(a);
		}
		is.close();
		is1.close();
		os.close();
		os1.close();
	}
}</span><span style="color:#0000ff;font-size: 13px;">
</span>

2.字符流

字符流又是 Reader 和 Writer了,顾名思义,它们处理的是字符数据,但是最底层的还是靠字节流实现的,所以Reader每次的 read()读的也是一个字节,只不过它有个转换器:InputStreamReader,他会把Reader读得的字节流转成字符流,这样每次处理的就是一个字符。 所以重头戏还是 InputStreamReader。

1) 字符的处理,一次处理一个字符(unicode编码)
2) 字符的底层仍然是基本的字节流
3) 字符流的基本实现
 InputStreamReader 完成byte流解析为char流,按照编码解析
 OutputStreamWriter 提供char流到byte流,按照编码处理
4) 字符流的过滤器
    是字符读写的功能扩展,极大的方便了文本的读写操作
    BufferedReader : readLine()   一次读取一行
    PrintWriter : println()  一次打印一行
5)读取一个文本文件
 InputStream is = new FileInputStream("test.txt");
 Reader in = new InputStreamReader(is);
 BufferedReader reader = new BufferedReader(in);
 或者
 BufferedReader in = new BufferedReader(new FileReader(filename));

1)Reader

下面是例子

package IO;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;

public class Reader_Test {

	/**
	 * @param args
	 * @throws IOException 
	 */
	public static void main(String[] args) throws IOException {
		InputStream is = new FileInputStream("D:/test.txt");
		Reader r = new InputStreamReader(is);  //InputStreamReader是一个转换器,把字节流转成字符流
		BufferedReader bf = new BufferedReader(r);
		int a;
		while((a=bf.read())!=-1){
			System.out.println((char)a);
		}
	}

}
其实大部分时候都是用 字节流的,字符流都字节流给转成的。 InputStreamReader 的 read() 方法之一的每次调用,可能促使从基本字节输入流中读取一个或多个字节。所以当test.txt中都是字母(一个字节)时,bf.read()会只读到一个字节,当test.txt中是汉字时,会读到两个字节。直接打印汉字。


2)Writer

writer实在没啥好讲的,用的多是是 FileWriter 和 BufferedWriter

package IO;

import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;

public class Writer_Test {

	public static void main(String[] args) throws IOException {
		
		Writer fw = new FileWriter("D:/test1.txt");
		fw.write("我们");   //可以直接写入内容
		fw.flush();	    // 字符流采用缓存区,如果没把数据刷到文件里,文件是没有数据的。fw.close()也可以把流刷入文件
	}
}


最后总结下流程:

1.实例化流对象  InputStream  is = new FileInputStream(“xxxx”);

2.读取      is.read();

3.后续自由操作

4.关闭流             is.close();


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值