理解字节流
发布于2022-07-09 16:25:31,更新于2022-07-10 23:21:54,标签:java 文章会持续修订,转载请注明来源地址:https://meethigher.top/blog理解
先看代码吧。
字节流写入,常用的写法是两种形式。
一种是读一个写一个,如下。
1 | public static void main(String[] args) throws Exception { |
还有一种是读到内存里先存着,最后再一起写,如下。
1 | public static void main(String[] args) throws Exception { |
其实,我一开始疑问的是,字节流,读为啥是个int,写又是个int,而且这个范围还是0-255?难道是int表示的是读到内存里的字节流的偏移量?然后写的时候再将内存里偏移该大小的内容的写出去?难不成是读到了线程内存里?会不会存在多线程被别的线程给读取出去的情况?
以上是基础不扎实导致的思考,计算机课上虽然老师教过,但都是墨守成规,从来没去思考过,所以所学知识并没有真正串联起来。
此处int返回的是一个字节的值,这个值是闭区间0-255。
下面具体记录下,字节(byte)、位(bit)、字(word)之间的关系。
1个字节等于8个比特,按习惯上的写法,1B=8bit。比特英文翻译是binary digit (缩写bit,即二进制),比特也叫位。
对于64位操作系统,1个字就表示了64位,即64bit=8byte=1word。
对于32位操作系统,1个字就表示了32位,即32bit=4byte=1word。
比特是计算机存储数据的最小单位,而字节是计算机处理数据的基本单位。
二进制数位也叫做比特位,例如0101,这是4位二进制,即4比特。
1个字节等于8比特,即8位,那么,最小就是0000 0000,换算成十进制就是0;最大就是1111 1111换算成十进制就是1+2+4+8+16+32+64+128=255。
这就是1个字节的整型范围为0-255的原因。
未解决Bug
提到这里,不得不记录一下之前遇到的bug。
去年做一个日志实时预览功能,就是用户可以在线观看系统的实时日志输出,最初的思路是ws+流实现的。流死循环,读到写入的字节再写出去。但是,在logback对日志进行归档时,他是把内容读出去归档后,就将该日志文件所有内容删除(后来为了解决这个问题,手动的通过file进行clear),这就导致我的流读不到内容或者乱码了。
我下面用个简单的例子重现一下。
1 | public static void main(String[] args) throws Exception { |
我在input文件里面,输入你好,result同样有你好。
此时删除好字,result还是你好
再追加坏,result还是你好
再追加啊,result变成你好啊
最终的结果,input是你坏啊,result是你好啊
这时候,两边的结果完全不一样了
如果删除一个数字(占1字节),追加一个汉字(占3字节),此时只会写出2个字节,就会导致乱码。
流里面,应该有记录索引的偏移的。比如我现在字节边界是3,你给我删除了3个字节,那么再写入时,就得先补全这3个才行。
有人说用字符流,其实一个道理,也存在这个问题。
这个目前还不清楚如何解决,留个问号。