字节流和字符流到底怎么用

首先说明什么是流,流,可以想象为数据中的流水,水管里面流动的水,按顺序流出来。使用流进行数据文件的读写可以称之为流式读写,与之对比的是随机读写。流式读写也代表着顺序读写,比如一个word文档,只有按里面保存的数据顺序读出来才能还原里面的内容。你不可能先随便从某个字节开始读,一定是怎么存怎么读。因此对于一个流来说,如果想要获取文件中的第5个字节,那么你也只能先把前4个字节读出来,才能获取到第5个字节。对应的是随机读写就是可以从任意读取文件中的某一个位置的字节。

从字面意思上来理解,读取一个.mp4文件得用字节流,读取一个.txt文件得用字符流。
首先,不管什么格式的文件,mp4也好,txt也罢,他们在磁盘中都以二进制存在。字节输入流和字符输入流处理的也都是二进制数据,准确点来说是字节数据。也就是010101。所以说用字节流对象来处理字符格式的文件和使用字符流对象来处理字节流的文件未尝不可。说白了,往文件里边存数据也是按照字节来存。

//字节流读取文件:
File f =new File("test.txt");
FileInputStream ziJie = new FileInputStream(f);
byte b=ziJie.read();//读取一个字节

//字符流读取文件:
File f =new File("test.txt");
FileReader ziFu = new FileReader(f);
char c=ziFu.read()//从文件中读取一个字符。读取一个字符比较抽象,具体来说是从文件中读取2个字节,然后解码为一个Unicode字符。

从上面的代码看出,字节流ziJie和字符流ziFu都是一个对象,他们的参数都是一个文件f。既然是一个对象,这些对象的方法就可以读取磁盘中文件f中的0101字节流数据。可以从磁盘中把0101数据给拿出来。
因此区别就在于他们怎么处理这个0101数据了。

假设text.txt里面的数据是10011010 10100110 0110001…
字节流对象如何处理这个数据呢?
顾名思义,一个字节一个字节读出来,
那么,调用ziJie.read(),就是把10011010读出来。也就是读出一个byte。一个byte可以把它编码成一个ASCII字符。如果你知道这个文件保存的是整数,你可以每次读取四个字节的数据(java里边int占4个字节),之后在程序里边把它编码成整数,。如果你知道这个文件保存的是小数,你可以每次读取8个字节的数据(java里边double占8个字节),之后在程序里边把它编码成小数,如果你知道这个文件保存的是汉字,那么首先你得知道文件的编码,如果是unicode编码,那么你得每次读取4个字节,再转成相应的文字。如果里边存的是混合类型的数据,有int,char,Stirng,double,对象等,那么你每次读出来的是不同数量的字节,再进行相应转换,才能还原里边的数据。如果你不知道里边存的是什么,那你就没法读出来,或者说读出来的是乱码。所以只有知道了文件的格式,才能正确读出文件。

字节数据写入example.123文件:
在这里插入图片描述
在Java中,byte类型的取值范围也是[-128, 127]。
如果定义byte b = ‘a’;那么实际上byte等价于byte b=97.因为a的ascii编码是97.
java里面,byte和char区别很大,char是无符号类型,占两个字节,代表一个Unicode字符的编码,范围是[0,65535].
注意:data里面的数据是byte类型,而不是整数int类型
文件中的数据:
在这里插入图片描述
从example.123里把文件读出来:
在这里插入图片描述
上面的read(buffer,0,1000)是个重载函数,本质是循环调用read()函数1000次。把读出来的数据放入了一个byte[]数组中。
buff中的内容:
在这里插入图片描述

往example.666文件里面写入字符串,也就是文本:
在这里插入图片描述可以看到是先把字符串转换成字节的形式,再把字节写入文件中。因为文件中只能写入字节数据
字符串转换成字节需要指定编码,getBytes(“UTF-8”),就是转换成utf-8编码,如果是getByte(),不写编码,那就是使用系统默认编码。
在这里插入图片描述
文件里边的内容,是utf-8编码的,如果使用记事本打开,不按照utf-8的方式来读就会乱码。
读取example.666里面的数据:
在这里插入图片描述操作跟写入反过来,先把字节读出来放入一个byte数组中,然后对byte数组进行反编码,也就是解码。
总结就是Strign和byte[]转换时,需要指定编码。
上面的两个例子是往文件里面写入byte数据和String文本数据。那么如何写入int数据或其它数据呢,方法就是想办法把int转换成字节,再往里边存入呗。也可以使用java提供的ByteBuffer编码工具,可方便进行编码和解码。

字符流又是如何处理的呢?
顾名思义,字符流是负责处理字符的,因为我们用的最多的就是字符。
字符流对象处理处理的最基本的单元是Unicode码元,也就是2个字节。即当调用ziFu.read()它先会读出10011010 10100110。
先看看,字符流怎么写,怎么读。
以下为菜鸟教程的示例:
写入文件:
在这里插入图片描述
读取文件:
在这里插入图片描述
这里有两个问题。1是写入文件使用的writer函数并没有没有指定编码。2是读取文件的时候为什么是使用一个char[]数组来进行接收。
问题1,定义FileWriter对象的时候可以指定编码,FileWriter writer = new FileWriter(String file, Charset cs);这个好像java11以后才支持。不行的话就这样解决编码问题BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(fileName), “UTF-8”));
问题2,java虚拟机内部统一使用Unicode编码,并且使用char类型进行表示。String类型的本质是char[]数组。char[]可以和String相互转换。

简而言之,可以理解为字符是对字节流的一种封装,字符流只可以处理String类型的数据,只能往文件里面存入字符,而字节流可以处理各种各样的数据,不仅可以进行字符的存取,还可以往文件里边存入int类型、double类型甚至图片、视频等类型。

还有一种读写类是带buffer的,buffer是缓冲的意思,如果不用buffer的话每进行一次读写,都得操作一次磁盘,速度会很慢,使用buffer的话会提前把磁盘里边的数据一次性先放到内存中的buffer,然后再从buffer里面拿,或者写的时候字节数据先往buffer里边放着,然后再一次性往磁盘写。提高效率。

参考:
理解Java中字符流与字节流的区别
字符流与字节流的区别

其实看这个就够了JavaIO流

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值