java IO编程(二)字节流与字符流

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/huangxin388/article/details/84061856

在java中对数据流的操作分为输入与输出两种方式,而且针对此操作提供了一下两类支持。

  • 字节流(JDK 1.0开始提供):InputStream(输入字节流)、OutputStream(输出字节流); 
  • 字符流(JDK 1.1开始提供):Reader(输入字符流)、Writer(输出字符流)。

一、字节流

输出字节流 OutputStream

OutputStream类的常用方法
No. 方法 类型 描述
1 public void close() throws IOException 普通 关闭字节流
2 public void flush() throws IOException 普通 强制刷新
3 public abstract void write(int b) thorws IOException 普通 输出单个字节
4 public void write(byte[] b) throws IOException 普通 输出全部字节数组数据
5 public void write(byte[] b,int off,int len) throws IOExcption 普通 输出部分字节数组数据

:OutputStream类是个抽象类,同时实现了Closeable和Flushable接口,而Closeable继承了AutoCloseable接口,因此当使用完OutputStream后即使不手动关闭资源,系统也会自动将资源关闭

             

OutputStream类本身是一个抽象类,如果需要进行文件操作,可以使用FileOutputStream子类完成。 

FileOutputStream类的常用方法
No. 方法 类型 描述
1 public FileOutputStream(File file) throws FileNotFoundException 构造 将内容输出到指定路径,如果文件已存在则使用新的内容覆盖旧的内容
2 public FileOutputStream(File file,boolean append) throws FileNotFoundException 构造 如果将布尔参数设置为true,则表示追加新的内容到文件中

1.使用字节输出流将设置好的内容输出到指定文件中

package com.tjut.streamTest;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

public class StreamTest01 {
	
	public static void main(String[] args) throws IOException {
		//定义要输出文件的路径
		File file = new File("d:" + File.separator + "Demo" + File.separator + "Hello" + File.separator + "test.txt");
		//此时由于目录不存在,所以文件不能输出,应该首先创建目录
		if(!file.getParentFile().exists()) {
			file.getParentFile().mkdirs();
		}
		//利用OutputStream向文件输出信息时如果文件不存在,则会自动创建(不需要用户手动调用createNewFile()方法)
		OutputStream output = new FileOutputStream(file);
		String str = "没有月色的夜里,萤火虫用心点亮漫天的星";
		byte data[] = str.getBytes();
		output.write(data);
		output.close();
	}
	


}

读者可以尝试使用单个字节的方式输出

	for(int i = 0;i < data.length;i++) {
			output.write(data[i]);
		}

 或者输出部分字节数组的内容

output.write(data,6,6);

输入字节流 InputStream

InputStream的可以对比OutputStream来学习,同样是抽象类,也不需要手动关闭资源。

InputStream类的常用方法
No. 方法 类型 描述
1 public void close() throws IOException 普通 关闭字节输入流
2 public abstract int read() throws IOException 普通 读取单个字节
3 public int read(byte[] b) throws IOException 普通 将数据读取到字节数组中,同时返回读取的数据长度
4 public int read(byte[] b,int off,int len) throws IOException 普通 将数据读取到部分字节数组中,同时返回读取的数据长度

:read()方法读到结尾后会返回-1

 InputStream本身是一个抽象类,需要使用FileInputStream类来实现相应的文件操作

FileInputStream类的常用方法
No. 方法 类型 描述
1 public FileInputStream(File file) throws FileNotFoundException 普通 设置要读取文件数据的路径

 2.使用字节输入流读取指定文件中的数据,并将其输出到控制台

package com.tjut.streamTest;

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

public class StreamTest02 {
	
	public static void main(String[] args) throws IOException {
		//1.定义要输入文件的路径
		File file = new File("d:" + File.separator + "Demo" + File.separator + "Hello" + File.separator + "test.txt");
		if(file.exists()) {//判断文件是否存在
			//2.使用InputStream进行读取
			InputStream input = new FileInputStream(file);
			byte data[] = new byte[1024];//准备一个1024的字节数组
			int len = input.read(data);//3.进行数据读取,将内容保存到字节数组中
			input.close();//4.关闭输入流
			System.out.println(new String(data,0,len));
		}
	}

}

 你也可以尝试使用while循环,每次读取一个字节

	int foot = 0;
			int temp = 0;
			while((temp = input.read()) != -1) {
				data[foot++] = (byte)temp;
			}

二、字符流 

字符输出流Writer

        Writer是一个抽象类,实现了Appendable、Closeable(父接口AutoCloseable)和Flushable接口,因此也不需要手动关闭资源。利用Writer类可以实现字符数组(包含了字符串)的输出

Writer类的常用方法
No. 方法 类型 描述
1 public void close() throws IOException 普通 关闭字符输出流
2 public void flush() throws IOException 普通 强制刷新
3 public Writer append(CharSequence csq) throws IOException 普通 追加数据
4 public void write(String str) throws IOException 普通 输出字符串数据
5 public void write(char[] cbuf) throws IOException 普通 输出字符数组数据

Writer是一个抽象类,要针对文件内容进行输出,可以使用java.io.FileWriter类实现Writer类对象的实例化操作。

No. 方法 类型 描述
1 public FileWriter(File file) throws IOException 构造 设置输出文件
2 public FileWriter(File file,boolean append) throws IOException 构造 设置输出文件以及是否进行数据追加

 3.使用字符输出流将特定内容写入指定文件中

package com.tjut.streamTest;

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

public class StreamTest03 {
	public static void main(String[] args) throws IOException {
		//1.定义要输入文件的路径
		File file = new File("d:" + File.separator + "Demo" + File.separator + "Hello" + File.separator + "test.txt");
		if(!file.getParentFile().exists()) {//判断目录是否存在
			file.getParentFile().mkdirs();//创建文件目录
		}
		
		Writer write = new FileWriter(file);//2.实例化Writer对象
		String str = "美丽的梦和美丽的诗一样 \r\n" + "都是可遇而不可求的 \r\n" + 
				"常常在最没能料到的时刻里出现";
		write.write(str);//3.输出字符串数据
		write.close();//4.关闭输出流
	}
}

字符输入流Reader

        java.io.Reader类是实现字符数据输入的操作类,在进行数据读取时可以不使用字节数据,而直接依靠字符数据(方便处理中文)进行操作。 

Reader类的常用方法
No. 方法 类型 描述
1 public void close() throws IOException 普通 关闭字符输入流
2 public int read() throws IOException 普通 读取单个字符
3 public int read(char[] cbuf) throws IOException  普通 读取字符到字符数组中,返回读取长度
4 public long skip(long n) throws IOException 普通 跳过字节长度

Reader类实现了Closeable(父接口为AutoCloseable)和Readable接口,因此不需要手动关闭资源

        Writer类中存在直接输出字符串的操作,而Reader类中并没有直接返回字符串的操作,这是因为输出数据时可以采用追加模式,导致文件变得非常庞大。如果在Reader类中提供了直接读取全部数据的方式,就有可能造成内存溢出问题。

        Reader类是一个抽象类,要实现文件数据的字符流读取,可以利用FileReader子类为Reader对象实例化。

FileReader类的常用方法
No. 方法 类型 描述
1 public FileReader(File file) throws FileNotFoundException 构造 定义要读取的文件路径

4.使用Reader从指定文件中读取数据

package com.tjut.streamTest;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;

public class StreamTest04 {
public static void main(String[] args) throws IOException {
	//1.定义要输入文件的路径
	File file = new File("d:" + File.separator + "Demo" + File.separator + "Hello" + File.separator + "test.txt");
	if(file.exists()) {
		Reader reader = new FileReader(file);//2.为Reader类对象实例化
		char data[] = new char[1024];
		int len = reader.read(data);//3.进行数据读取
		reader.close();//4.关闭输入流
		System.out.println(new String(data,0,len));
	}
}
}

字节流与字符流的区别

        字节流直接与终端文件进行数据交互,字符流需要将数据经过缓冲区处理才与终端文件数据交互。在使用OutputStream输出数据时即使最后没有关闭输出流,内容也可以正常输出,但是反过来如果使用的是字符输出流Writer,在执行到最后如果不关闭输出流,就表示在缓冲区中处理的内容不会被强制性清空,所以就不会输出数据。如果有特殊情况不能关闭字符输出流,可以使用flush()方法强制清空缓冲区。

5.强制清空字符流缓冲区

package com.tjut.streamTest;

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

public class StreamTest05 {
	
	public static void main(String[] args) throws IOException {
		//1.定义要输出文件的路径
		File file = new File("d:" + File.separator + "Demo" + File.separator + "Hello" + File.separator + "test.txt");
		if(!file.getParentFile().exists()) {//判断目录是否存在
			file.getParentFile().mkdirs();//创建文件目录
		}
		
		Writer writer = new FileWriter(file);//2.实例化Writer类对象
		String str = "我喜欢那样的梦 \r\n" + 
				"在梦里 一切都可以重新开始 \r\n" + 
				"一切都可以慢慢解释 \r\n" + 
				"心里甚至还能感觉到所有被浪费的时光 \r\n" + 
				"竟然都能重回时的狂喜和感激";
		writer.write(str);//3.输出字符串数据
		writer.flush();//强制刷新缓冲区
	}

}

:在开发中,如果要处理中文时应优先考虑字符流,如果没有中文问题,建议使用字节流。

三、转换流 

        虽然字节流和字符流表示两种不同的数据流操作,但是这两种流彼此间是可以实现相互转化的,虽然转换流的使用情况并不多。

转换流用到的方法
名称 InputStreamReader OutputStreamReader
定义结构 public class InputStreamReader extends Reader public class OutputStreamWriter extends Writer
构造方法 public InputStreamReader(InputStream in) public OutputStreamWriter(OutputStream out)

6.将字节输出流(OutputStream)转换为字符输出流(Writer)

package com.tjut.streamTest;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;

public class StreamTest06 {
	
	public static void main(String[] args) throws IOException {
		//1.定义要输出文件的路径
		File file = new File("d:" + File.separator + "Demo" + File.separator + "Hello" + File.separator + "test.txt");
		if(!file.getParentFile().exists()) {//判断目录是否存在
			file.getParentFile().mkdirs();//创建目录
		}
		OutputStream output = new FileOutputStream(file);//字节流
		//将OutputStream类对象传递给OutputStreamWriter类的构造方法,而后向上转型为Writer
		Writer writer = new OutputStreamWriter(output);
		String str = "胸怀中满溢著幸福\r\n" + 
				"只因为你就在我眼前\r\n" + 
				"对我微笑 一如当年\r\n" + 
				"我真喜欢那样的梦";
		writer.write(str);//Writer类的方法
		writer.flush();
		writer.close();
	}

}

 文件操作类的继承结构如下:

        通过继承结构可以发现,FileWriter与FileReader都是转换流的子类,也就证明所有要读取的文件数据都是字节数据,所有 的字符都是在内存中处理后形成的。 

猜你喜欢

转载自blog.csdn.net/huangxin388/article/details/84061856