JavaIO的编解码、字节流和字符流的区别和转换

本文深入探讨Java IO流的基础概念,对比字节流与字符流的特点,并解析编码与解码的过程。通过实例展示如何手动为字节流进行编解码以支持中文读写,同时讨论了字符流与字节流的应用场景及优缺点。

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

  刚刚学习JavaIO流, 可能会很乱, IO流怎么这么多东西啊, 如果对JavaIO体系不熟悉,请查阅先的博客.

https://blog.youkuaiyun.com/huangchongwen/article/details/80866984

 今天复习的主题是 -- JavaIO流的编解码, 字符流与字节流区别!


 一 : 字节流、字符流读写


  案例1 : 字节流读取中文.

private static void readFileByInputStream2(String path) throws IOException {

       FileInputStream fis = new FileInputStream(path);

       int len = 0;

       while ((len = fis.read()) != -1) {

           System.out.print((char) len);

       }}

    }

}


 运行结果我们都知道, 含有中文很可能出现乱码! 原因是什么?字节流本身不会自动编解码, 而使用字符流则没有问题, 字符流具有自动编解码效果

二: 编码与解码

  String 类型-》byte 就是编码过程,    byte-》String 类型 解码过程! 假如我们还是想要使用字节流读写中文, 那可以手动为字节流编码与解码! 
private static void writeFileByOutputStream(String path, String content)
			throws IOException {
		FileOutputStream fos = new FileOutputStream(path);

		// 把字符串进行编码操作
		byte[] bytes = content.getBytes("utf-8");
		// 内容通过字节流写入到文件中。
		fos.write(bytes);
		fos.close();
	}

	private static void readFileByInputStream(String path) throws IOException {
		FileInputStream fis = new FileInputStream(path);
		int len = 0;
		byte[] buffer = new byte[1024];

		while ((len = fis.read(buffer)) != -1) {
			// 二进制解码,使用系统默认编码
			System.out.println(new String(buffer, 0, len,"utf-8"));
		}

	}

我们手动为字节流编解码, 同样可以读写中文! 刚刚学习IO流, 经常听说: 字符流=字节流+编码表。反过来理解一下, 字节流+自动编码=字符流。字符流可以自动编码(使用系统默认的码表), 字节流可以手动编码实现和字符流类似的功能! 如果不能理解这个, 那来看看先代码。

os=new FileOutputStream(file);
String str=new String("hello gay!");
              // os.write(str); 不编码--错误
os.write(str.getBytes());// 按照默认的GBK编码String c="我是中国人!";
w=new FileWriter(filepath,true);
w.write(c);//不需要编码都正确


三  字符流的弊端


 字节流和字符流那个更加强大? 应该是字节流. 字符流可以做到的字节流都可以, 但是字节流做到的字符流不一定可以做到。比如拷贝媒体文件(图片、视频等)。

拷贝文件使用字节流而不使用字符流,因为字符流读文件涉及到解码,会先解码,写文件的时候又涉及到编码,这些操作多余,而且读和写的码表不对应还容易引发问题。一句话解释就是:媒体文件的二进制数据是纯二进制,不是有意义的字符,所以码表无法转换。


四 转换流 

    InputStreamReader 是字节流通向字符流的桥梁,是字节流->字符流 ,不能逆向。很显然可以包装我们的字节流,自动的完成节流编码和解码的工作。

    注意: 码表不对应,发现都会出现乱码的问题.

public class Demo4 {

    public static void main(String[] args) throws IOException {

       File file = new File("c:\\a.txt");

       File fileGBK = new File("c:\\gbk.txt");

       File fileUTF = new File("c:\\utf.txt");

       // 默认编码

       testReadFile(file);

       // 传入gbk编码文件,使用gbk解码

       testReadFile(fileGBK, "gbk");

       // 传入utf-8文件,使用utf-8解码

       testReadFile(fileUTF, "utf-8");

 

    }

 

    // 该方法中nputStreamReader使用系统默认编码读取文件.

    private static void testReadFile(File file) throws

           IOException {

       FileInputStream fis = new FileInputStream(file);

       InputStreamReader ins = new InputStreamReader(fis);

       int len = 0;

       while ((len = ins.read()) != -1) {

           System.out.print((char) len);

       }

       ins.close();

       fis.close();

    }

 

    // 该方法使用指定编码读取文件

    private static void testReadFile(File file, String encod)

           throws IOException {

       FileInputStream fis = new FileInputStream(file);

       InputStreamReader ins = new InputStreamReader(fis, encod);

       int len = 0;

       while ((len = ins.read()) != -1) {

           System.out.print((char) len);

       }

       ins.close();

       }

}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值