IO流

转自:https://blog.csdn.net/u010687392/article/details/43567325
数据类型:
字节流
字节输入流 InputStream
字节输出流 OutputStream
字符流
字符输入流 Reader
字符输出流 Writer

那么字节流和字符流有什么区别呢?
一般来说,字符流是为了更好的处理中文字符而出现的,比字节流晚出现,在对中文字符进行操作时,建议使用字符流,但是使用字节流也可以,因为字节流是万能的。

字节流读写:
向一个文件中写入数据:

public static void main(String[] args) throws IOException {
		FileOutputStream fos = new FileOutputStream("demo.txt");// 传入的是一个文件对象或者文件名,默认是当前项目目录下,
		//要是想放在其它地方,则以这样的格式就行,d:\\demo\\demo.txt,这样就相当于在d盘的demo目录下创建了demo.txt的文件.注意,
		//输出流即OutputStream会自动创建这个文件,而输入流InputStream则不会.很简单,你要从一个文件中
		//读数据是不是要有一个文件才能读啊?写数据时候如果没有这个文件就会自动帮你创建这个文件。
		String str = "hello 中国";
		byte[] bytes = str.getBytes();//把字符串转化为字节数组
		fos.write(bytes);//这里传入的是一个byte[]数组,必须把写入的数据转化为字节数组才能写。
		fos.close();//关闭资源
	}

追加写入:

FileOutputStream fos = new FileOutputStream("demo.txt");方式写数据,是从文件的开始写的,相当于把之前的数据覆盖了,
我要是想在一个文件中的结尾开始写数据呢?那怎么办?很简单,
在FileOutputStream fos = new FileOutputStream("demo.txt",true)加一个参数true,
或者在fos.write(bytes,true)第二个参数中加true,都是表示是以追加数据的形式写数据。

把一个文件中的数据读出来:

public static void main(String[] args) throws IOException {
		FileInputStream fis = new FileInputStream("demo.txt");
		int by = -1;
		while((by = fis.read())!=-1){//fis.read()表示一个字节一个字节的读数据,该返回值是int类型的值,是读取到数据的
		ascii表中对应的值,比如a对应ASCII表中的值是97,那么它返回的就是97,返回-1就说明读完了,如果文件中有换行,那它也会读,
		读的字符为\n。
		System.out.print(by+" ");//输出的为Ascll对应的值104 101 108 108 111 32 214 208 185 250,要输出字符,可以把它
		转化为字符,即(char)by; 
		}
		fis.close();
	}

这样一个字节一个字节的读和写是不是效率太低了呢?有没有更高效率的方法呢?肯定有的,那就是以一个字节数组的大小来读和写,一次读一个字节数组和写一个字节数组的数据。
以字节数组方式读取和写入数据:

public static void main(String[] args) throws IOException {
		FileInputStream fis = new FileInputStream("a.txt");
		FileOutputStream fos = new FileOutputStream("b.txt");
		byte[] bytes = new byte[1024]; //定义一个1024个字节大小的字节数组
		int len = -1;
		while ((len = fis.read(bytes)) != -1) {//fis.read(bytes)表示一次读1024个字节存储到字节数组中,该返回值是读取到
		字节的长度,这和读取单个字节的返回值并不一样,需要注意!!!
			//fos.write(bytes);不要这样写,应该以下面这种方式写
			fos.write(bytes,0,len);//该表示写入刚刚读取时存储到bytes字节数组中的数据,从0开始,到数组下标为len之间的数据
			写入,这个必须要加。因为如果不加,可能文件末尾读取的字节数据不到1024个数组大小,直接写入的话会写入上次后面没有
			被覆盖的值,导致数据不一致。
		}
		fos.close();
		fis.close();
	}

虽然上面的方式以字节数组来读写比较高效,但是还有一种以字节缓冲区来读写的,这种方式是最高效的。
字节缓冲区流:
A:BufferedOutputStream
B:BufferedInputStream
使用起来也非常简单,即:把字节流包装在字节缓冲流里面即可,用法一样,相当于把之前的流装饰了一下:

public static void main(String[] args) throws IOException {
		//BufferedOutputStream实际上自己内部有一个缓冲的字节数组
		BufferedInputStream bis = new BufferedInputStream(new FileInputStream("杏花弦外雨.mp3"));//传入的是一个
		InputStream对象
		BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("杏花弦外雨2.mp3")); 
		byte[] bytes = new byte[1024];
		int len = -1;
		while((len=bis.read(bytes))!=-1){
			bos.write(bytes, 0, len);
			bos.flush();//刷新此缓冲的输出流,将缓冲区的数据写入文件
		}
		bos.close();
		bis.close();
	}

字符流
可以这样理解,字符流 = 字节流 + 编码表,目的是为了更好的操作中文字符

字符流只可以可以操作字符类型的文件,不能操作影音图像文件,要操作这些文件必须使用字节流

A:OutputStreamWriter
父类Writer
1、OutputStreamWriter(OutputStream os):默认编码,GBK
2、OutputStreamWriter(OutputStream os,String charsetName):指定编码。

B:InputStreamReader
父类Reader
1、InputStreamReader(InputStream is):默认编码,GBK
2、InputStreamReader(InputStream is,String charsetName):指定编码

编码问题只要输入和输出流的编码一致即可。

C:FileWriter
父类 OutputStreamWriter
1、FileWriter(File file)
2、FileWriter(String fileName)
3、FileWriter(File file, boolean append)

用来写入字符文件的便捷类 ,通常我们操作字符流采取这个类即可,因为它是继承自OutputStreamWriter的类,方法和父类的一样,而且构造方法比较简便,当然使用上面的OutputStreamWriter(OutputStreamos)也行,参数是一个字节流对象。

D:FileReader
父类InputStreamReader

用来读取字符文件的便捷类

E:BufferedWriter
父类Writer
BufferedWriter(Writer out)

将文本写入字符输出流,缓冲各个字符,从而提供单个字符、数组和字符串的高效写入。

F:BufferedReader
父类Reader
BufferedReader(Reader in)

从字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取。

为了获得最高效率,可考虑将 OutputStreamWriter或FileWriter 包装到 BufferedWriter 中,
将 OutputStreamReader或FileReader 包装到 BufferedReader 中。

OutputStreamWriter和InputStreamReader代码:

public static void OutputStreamWriter() throws IOException{
		OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("c.txt"));
		char[] ch = new char[]{'a','b','c','d','e'};
		osw.write(ch);//字符数组形式写入
		osw.write(ch, 0, 3);//字符数组一部分写入
		osw.write("你好吗");//字符串形式写入
		osw.flush();//刷新,将缓冲区的数据写入到文件中
		osw.close();
		InputStreamReader isr = new InputStreamReader(new FileInputStream("c.txt"));
		char[] ch2 = new char[1024];
		int len = -1;
		while((len = isr.read(ch2))!=-1){//一次读1024个字符
			System.out.print(new String(ch2,0,len));//将读取到的字符转化为字符串显示出来
		}
		isr.close();
	}

FileWriter 和FileReader 代码:

public static void FileWriterDemo() throws IOException{
		FileReader fr = new FileReader("a.txt");//创建一个读取字符流对象,并指向a.txt这个文件
		FileWriter fw = new FileWriter("b.txt");
		char[] ch = new char[1024];
		int len = -1;
		while((len=fr.read(ch))!=-1){//一次读1024个字符
			fw.write(ch, 0, len);//将读到多少数据写入缓冲区中
			fw.flush();//刷新缓冲区把数据写入文件中
		}
		fw.close();
		fr.close();
	}

最高效的BufferedWriter 和BufferedReader,缓冲字符流代码:

public static void Bufferwriter() throws IOException{
		//BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("a.txt")));
		BufferedReader br = new BufferedReader(new FileReader("a.txt"));//包装字符流
		BufferedWriter bw = new BufferedWriter(new FileWriter("b.txt"));//包装字符流
		int len = -1;
		char[] cbuf = new char[1024];
		while((len=br.read(cbuf))!=-1){
			bw.write(cbuf, 0, len);//将读到多少数据写入缓冲区中
			bw.flush();//刷新缓冲区把数据写入文件中
		}
		bw.close();
		br.close();
	} 

BufferedReader特有方式,一次读取一行的数据,即读一行字符串:

public static void BufferDemo() throws IOException{
		BufferedReader br = new BufferedReader(new FileReader("a.txt"));
		BufferedWriter bw = new BufferedWriter(new FileWriter("b.txt"));
		String line = null;
		while((line=br.readLine())!=null){//br.readLine()返回值是一个字符串,因为它是一次读取一行字符串数据。当它返回值
		为null时,表示读取完毕
			bw.write(line);//写入刚刚读取到的字符串到缓冲区
			bw.newLine();//换行
			bw.flush();//将缓冲区的字符串写入文件中,如果不刷新,那么就没有数据写入
		}
		bw.close();//将写入流关闭时会默认刷新一遍缓冲区,建议在每写一遍数据时候调用flush()刷新一遍
		br.close();
	}

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值