JAVA文件读写之OutputStreamWriter,BufferedWriter和 InputStreamReader,BufferedReader

本文介绍如何使用OutputStreamWriter和InputStreamReader解决不同文件编码下的读写乱码问题,通过BufferedWriter和BufferedReader提高效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

直接使用FileOutputStream 字节流和FileInputStream 字节流对文件读写可能改变文件编码和读取到乱码。
eg:ANSI文档

直接用FileInputStream读取结果为:

ʹ��ANSI���롣

接下来用FileOutputStream直接写入内容并用FileInputStream读写结果为:将ANSI改变为UTF-8

写入完毕
我有一只小毛驴,从来也不骑
test.txt
C:\Users\Administrator\Desktop\test.txt

我们看到文件的编码变了,可以直接用FileInputStream读取并且没有乱码。
为了解决乱码问题我们就要针对文件的不同编码来进行读写,我们要使用OutputStreamWriter,BufferedWriter和 InputStreamReader,BufferedReader。
首先看一下API对他们的描述:

OutputStreamWriter 是字符流通向字节流的桥梁:可使用指定的 charset 将要写入流中的字符编码成字节。它使用的字符集可以由名称指定或显式给定,否则将接受平台默认的字符集。
每次调用 write() 方法都会导致在给定字符(或字符集)上调用编码转换器。在写入底层输出流之前,得到的这些字节将在缓冲区中累积。可以指定此缓冲区的大小,不过,默认的缓冲区对多数用途来说已足够大。注意,传递给 write() 方法的字符没有缓冲。
为了获得最高效率,可考虑将 OutputStreamWriter 包装到 BufferedWriter 中,以避免频繁调用转换器。例如:
Writer out
= new BufferedWriter(new OutputStreamWriter(System.out));

InputStreamReader 是字节流通向字符流的桥梁:它使用指定的 charset 读取字节并将其解码为字符。它使用的字符集可以由名称指定或显式给定,或者可以接受平台默认的字符集。
每次调用 InputStreamReader 中的一个 read() 方法都会导致从底层输入流读取一个或多个字节。要启用从字节到字符的有效转换,可以提前从底层流读取更多的字节,使其超过满足当前读取操作所需的字节。
为了达到最高效率,可要考虑在 BufferedReader 内包装 InputStreamReader。例如:
BufferedReader in
= new BufferedReader(new InputStreamReader(System.in));

看一下他们的参数:

OutputStreamWriter(OutputStream in,
String charsetName)
InputStreamReader(InputStream in,
String charsetName)

其中in分别为字节输入输出流, charsetName是文件编码方式。
从API文档可以看到为了提升效率一般将他们包装到BufferedWriter和BufferedReader,包装方式API已经给出就不累赘了。
接下来看实际代码:

package file;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
/**
 * OutputStreamWriter,BufferedWriter和 InputStreamReader,BufferedReader输入输出演示
 *@author 摸打滚爬一路向前
 */
public class File_class {
	private File file;//创建文件和目录路径名的抽象表示形式变量。
	/**构造函数**/
	public File_class(String url,String name) {
		file=new File(url, name);
	}
	/**构造函数**/
	public File_class(String url) {
		file=new File(url);
	}
	/**
	 * 获取文件名
	 * @return String
	 */
	public String getFileName() {
		return file.getName();
	}
	/**
	 * 获取文件路径
	 * @return String
	 */
	public String getFilePath() {
		return file.getPath();
	}
	/**
	 * 创建字节流向文件写数据<br>
	 * 从创建的对象fil处获取字节流
	 * @return void
	 * @throws FileNameException 
	 */
	public void writeFile() throws FileNameException {	
		try {
			FileOutputStream outputStream=new FileOutputStream(file);
			OutputStreamWriter writer=new OutputStreamWriter(outputStream,"GBK");
			BufferedWriter bufferedWriter=new BufferedWriter(writer);
		    bufferedWriter.write("你好");
			System.out.println("写入完毕");
			bufferedWriter.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		
	}
	public void readerFile()throws FileNameException {
		if (!file.exists()) {
			throw new FileNameException("读取文件路径不存在");
		}
		else if ( file.length() == 0) {
			System.out.println("空文件");
			return ;
		}else {
		try {   
			FileInputStream in=new FileInputStream(file);
		    BufferedReader bufferedReader=new BufferedReader(
		  		new InputStreamReader(in, "GBK"));
		    StringBuffer buffer=new StringBuffer();
		    char[] buf=new char[64];
		    int count=0;
		    	while((count=bufferedReader.read(buf))!=-1) {
		    		buffer.append(buf,0,count);
		    	}
			 bufferedReader.close();
			 System.out.println(buffer);
		} catch (Exception e) {
			e.printStackTrace();
		}
		}
		
	}
	public static void main(String[] args) throws FileNameException {
		File_class file_class=new File_class("C:\\Users\\Administrator\\Desktop\\test.txt");
		file_class.writeFile();
		file_class.readerFile();
		System.out.println(file_class.getFileName());
		System.out.println(file_class.getFilePath());
		}
}
/**
 * 自定义异常类
 * @author 摸打滚爬一路向前
 *
 */
class FileNameException extends Exception{
	private static final long serialVersionUID = -3599721275508980926L;
	String message;
	public FileNameException(String ErrowMesssge) {
		message=ErrowMesssge;
	}
	public String getMessage() {
		return message;
	}
}

如想看代码具体注释请看:https://blog.youkuaiyun.com/qq_42650817/article/details/85018703

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值