Java IO Stream/IO Reader 详解

JAVA herman 697浏览 0评论
公告:“业余草”微信公众号提供免费CSDN下载服务(只下Java资源),关注业余草微信公众号,添加作者微信:xttblog,发送下载链接帮助你免费下载!
本博客日IP超过1800,PV 2600 左右,急需赞助商。
极客时间所有课程通过我的二维码购买后返现24元微信红包,请加博主新的微信号:xttblog,之前的微信号好友位已满,备注:返现
所有面试题(java、前端、数据库、springboot等)一网打尽,请关注文末小程序
视频教程免费领

Java IO 流总共涉及到几十个类。分字符流,字节流,还有读写等。如果你能彻底的搞懂它们之间的关系,薪资应该不会低。

本文根据 Java 中 IO 流的结构图,梳理了几个比较重要的常用的 IO 读写类。

输入流和输出流的类层次图。

Java IO 流

FileInputStream/FileOutputStream

这是两个常用的文件读写操作类。

使用例子如下:

public class InputRead {
    public static void main(String[] args) {
        String filename_a = "lxf_a.txt";
        String filename_b = "lxf_b.txt";
        InputStream inputStream = new FileInputStream(filename_a);
        OutputStream outputStream = new FileOutputStream(filename_b,true);
        //a.单字节读取,循环读取文件,每次读取一个字节,如果读到文件末尾,返回-1
//        int b;
//        while ((b=inputStream.read())>0) {//for (;(b=inputStream.read())>0;) {
//            outputStream.write(b);
//        }
        //b.多字节读取,将文件中数据读满(如果足够)字节数组
        int num = inputStream.available();
//        byte[] by1 = new byte[num];
//        int b1 = inputStream.read(by);
        byte[] by2 = new byte[num];//num不固定
        int b2 = inputStream.read(by2, 0, num);
        System.out.println("length="+b2+",context:"+new String(by2));
        outputStream.write(by2);
    }
}

FilterInputStream/DataInputStream

FilterInputStream 结构图

java每个int是4个字节,而InputStream的read是面向字节的,也就是每次只能读取1个字节,因此在readInt这个方法中,读取出4个字节,再进行处理成一个int。

DataOutputStream out = new DataOutputStream(new FileOutputStream("lxf.txt"));  
out.writeInt(123);  
out.writeUTF("你好");  
out.writeBoolean(true);  
out.flush();  
out.close();  
// 业余草:www.xttblog.com
DataInputStream in = new DataInputStream(new FileInputStream("lxf.txt"));  
int a = in.readInt();  
System.out.println("first int is "+a);  
String b = in.readUTF();  
System.out.println("second string is "+b);  
boolean c= in.readBoolean();  
System.out.println("third boolean is "+c);  
in.close();

BufferedInputStream/BufferedOutStream

有一个buf[],也就是用来当做缓存的字节数组。每次调用read/write读写数据时,先查看要读写的数据是否在缓存中,如果在缓存中,直接从缓存中读取  ;如果不在缓存中,则调用fill方法,从InputStream中读取一定的存储到buf中。
// BufferedStream复制  
public void copyByBuffer() throws IOException {  
	InputStream inputStream = new FileInputStream("lxf_a.txt");
	OutputStream outputStream = new FileOutputStream("lxf_b.txt",true);
	BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);
	
	BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(outputStream);
	int num = bufferedInputStream.available();
	byte[] by3 = new byte[num];//num不固定
	int b3 = bufferedInputStream.read(by3);
	System.out.println("length="+b3+",context:"+new String(by3));
	bufferedOutputStream.write(by3);
	bufferedOutputStream.flush();
	//bufferedInputStream.close();
	//bufferedOutputStream.close();
	inputStream.close();
	outputStream.close();
}  
// FileInputStream复制  
public void copy() throws IOException {  
	FileInputStream in = new FileInputStream(file);  
	FileOutputStream out = new FileOutputStream(file_cp);  
	byte[] buf = new byte[1024];  
	int len = 0;  
	while ((len = in.read(buf)) != -1) {  
		out.write(buf);  
	}  
	in.close();  
	out.close();  
} 

InputStreamReader/OutPutStreamWriter

OutPutStreamWriter 这个类,可能大部分人都没有用过。

public static void IoStreamReaderTest() throws IOException {
	/**
	 * 没有缓冲区,只能使用read()方法。
	 */
	//读取字节流
	InputStream in = new FileInputStream("lxf_a.txt");//读取文件的数据。

	//将字节流向字符流的转换。要启用从字节到字符的有效转换,可以提前从底层流读取更多的字节.
	InputStreamReader isr = new InputStreamReader(in);//读取
	OutputStreamWriter osr = new OutputStreamWriter(new FileOutputStream("lxf_b.txt"));//输出
	char []cha = new char[1024];
	int len = isr.read(cha);
	System.out.println(new String(cha,0,len));
	osr.write(cha);
	osr.flush()
	isr.close();
	osr.close();
}

FileReader/FileWriter

FileWriter和FileReader是用来实现将字符读写到文件的IO类。

public static void FileWriterReaderTest() throws IOException {
	File file = new File("lxf.txt");
	file.createNewFile();
	FileWriter fileWriter= new FileWriter(file);
	fileWriter.write("liu xin feng,\nlove you!");
	fileWriter.flush();
	fileWriter.close();

	// 创建 FileReader 对象
	FileReader fr = new FileReader(file);
	char [] a = new char[22];
	int n = fr.read(a); // 读取数组中的内容
	System.out.println(n); // 一个一个打印字符
	for(char c : a)
		System.out.print(c); // 一个一个打印字符
	fr.close();
}

BufferedReader/BufferedWriter

  1. java.io.BufferedReader和java.io.BufferedWriter类各拥有8192字符的缓冲区。当BufferedReader在读取文本文件时,会先尽量从文件中读入字符数据并置入缓冲区,而之后若使用read()方法,会先从缓冲区中进行读取。如果缓冲区数据不足,才会再从文件中读取,使用BufferedWriter时,写入的数据并不会先输出到目的地,而是先存储至缓冲区中。如果缓冲区中的数据满了,才会一次对目的地进行写出。
  2. 从标准输入流System.in中直接读取使用者输入时,使用者每输入一个字符,System.in就读取一个字符。为了能一次读取一行使用者的输入,使用了BufferedReader来对使用者输入的字符进行缓冲。readLine()方法会在读取到使用者的换行字符时,再一次将整行字符串传入。
  3. System.in是一个位流,为了转换为字符流,可使用InputStreamReader为其进行字符转换,然后再使用BufferedReader为其增加缓冲功能。例如:BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); 
/*
 * 字符读取流缓存区
 * 	该方法提供了一个每次读取一行内容的方法.readLine(),方便对文本数据的获取。
 */
public static void BufferedReaderDemo() throws IOException{
	//创建一个读取流对象和文件相关联
	FileReader fReader = new FileReader("bfWriter.txt");
	//为了提高效率,加入缓存技术,将字符流对象传递缓存对象的构造函数
	BufferedReader bfReaed = new BufferedReader(fReader);
	String line = null;
	while ((line = bfReaed.readLine())!=null) {//每次读取一行
		System.out.println(line); //上面返回的line中的readLine方法中不包含换行符
	}
	bfReaed.close();
}
/*字符写入流缓存区
 * 	在java中为了提高FileWriter的写入效率,出现了BufferedWriter缓存技术
 * 	缓存区的出现是为了提高流的操作效率而出现的,所以在创建缓存区之前,必须要先有流对象
 * 	该缓存区中提供了一个跨平台的换行符就是.newLine()
 */
public static void BufferedWriterDemo() throws IOException{
	//创建一个字符写入流对象
	FileWriter fWriter = new FileWriter("bfWriter.txt");
	//为了提高字符写入流的效率,加入了缓冲技术
	//只要将需要被提高效率的流对象作为参数传递给缓冲区的构造函数即可
	BufferedWriter  bfWriter =new BufferedWriter(fWriter);
	for (int i = 0; i < 5; i++) {
		bfWriter.write("abcdefg");
		bfWriter.newLine();
	   bfWriter.flush(); //刷新内容
	}
	//记住,只要用到缓冲区,就要记得刷新。
	//fWriter.flush();//31行34行两个flush区别
	//其实关闭缓存区,就是在关闭缓存区中流对象,所有不再需要关闭fWriter对象
	bfWriter.close();
}

业余草公众号

最后,欢迎关注我的个人微信公众号:业余草(yyucao)!可加QQ1群:135430763(2000人群已满),QQ2群:454796847(已满),QQ3群:187424846(已满)。QQ群进群密码:xttblog,想加微信群的朋友,之前的微信号好友已满,请加博主新的微信号:xttblog,备注:“xttblog”,添加博主微信拉你进群。备注错误不会同意好友申请。再次感谢您的关注!后续有精彩内容会第一时间发给您!原创文章投稿请发送至532009913@qq.com邮箱。商务合作可添加助理微信进行沟通!

本文原文出处:业余草: » Java IO Stream/IO Reader 详解