字节数组转换为字符串,然后再转回字节数组会有损失

首先看下面一个例子:

    File file1=new File("F:/Wangchuang/eclipse/eclipse.exe-0");byte[] bytes2=new byte[(int) file1.length()];FileInputStream fis=new FileInputStream(file1);fis.read(bytes2);fis.close();System.out.println(bytes2.length);String s2=new String(bytes2);System.out.println(s2.length());

执行结果:

 10240078479
 public static void ceshi(String filepath) {File file=new File(filepath);try(FileInputStream fis=new FileInputStream(file)){byte[] b=new byte[(int)file.length()];fis.read(b);System.out.println("文件编码方式为UTF-8,内容为中国,占用三个字节");System.out.println("采用系统默认的译码方式:"+new String(b)); } catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}

执行结果

文件编码方式为UTF-8,内容为中国,占用三个字节
采用系统默认的译码方式:涓浗

可以看出这字节数组和字符串的长度不一致。不一致的原因是一个字符占用一个或者多个字节。new String()函数会将字节本身所携带的编码方式抛弃,然后改用系统默认的编码方式对字节信息进行译码。这可能导致文件是”中国“,而经过new String()之后就不是“中国”了。
下面为测试代码:

先把这个问题放一放,看下面一个代码,执行出来,数据没有发生损失。

 File file1=new File("F:/Wangchuang/eclipse/eclipse.exe-0");byte[] bytes2=new byte[(int) file1.length()];FileInputStream fis=new FileInputStream(file1);fis.read(bytes2);fis.close();char[] char1=new char[bytes2.length];//用循环会很麻烦,对于大数据的话,计算时间很久for(int i=0;i<bytes2.length;i++) {char1[i]=(char)bytes2[i];}System.out.println(char1.length);String s3=new String(char1);System.out.println(s3.length());

执行结果:

 102400102400

虽然对于char[]数组不会发生数据损失,但是当这个字符串直接转换为字节数组的时候,会发生文件损坏解决办法是,字符串先转换为char数组然后在转换为byte[]

从上面两个代码块就知道,String函数对于char和byte的处理是不一样的,至于哪里不一样,现在研究一下。

Java中String内置的public String(byte[] bytes)和public byte[] getBytes()对于不合法的utf-8字节流在解析时会增删字节。

查了几个文章,有助于对这个问题的理解:

关于这个问题的问答

对于这个问答里面有一个解答是说,字符编码遇到了终止符,经过测试不可靠。主要原因是因为有字节的增删。

byte[]转换为字符串数据丢失的问题

参考
程序中用到了MD5加密和IDEA加密,通过这些算法得出的结果均是字节码,但是我程序中使用一个通讯接口,其接受的参数类型为String。所以在发送时,需要转换为String。

对于java来说,byte只能表示有符号的数据即范围为-128~127,所以对于编码后,如果原本字节流中的信息有大于127的话,将其转换成String类型,发送的时候再转换为byte[]时,会出现与原始字节码不一致的现象。

因为在java中如果找不到合适的字符的话,默认会用’?‘代替,如对于0xC9,很显然无法表示成字符,所以在进行byte[]->String->byte[]的时候,就会变成0x3F(’?’)。

此时可以通过字符编码的方式来解决:在进行byte[]->String的转换时,利用"new String(byteArray, “ISO-8859-1”);"得到String。在进行String->byte[]的时候,再通过pkt.getBytes(“ISO-8859-1”)得到原始byte[],这样数据就不会出现错误。

经过测试,这个方法可以解决数据丢失的问题,文件的合并不会发生损坏
可以参考这篇文章里的:练习合并文件

byte[]to String 引起的bug
参考

什么是字节?

位是计算机内部的最小数据储存单位,8位就组成了1字节,也就是java中的byte。

什么是字符?

字符是指字母、数字、特殊符号的集合,也就是java中的char和String。

字节怎么就变成了字符?

答案是字符编码。比较出名的字符集是ascii、gb2312、utf-8等。其中ascii和gb2312是定长字符编码,一个字符分别占用1字节、2字节,而utf-8是变长字符编码,最短为1字节,最常为4字节。

以ascii为例,字母A在计算机中的存储为0b0100 0001。

Java中String内置的public String(byte[] bytes)和public byte[] getBytes()对于不合法的utf-8字节流在解析时会增删字节。

立贴再此!以后查看!

字节数组转换为字符串会造成数据损失的一些解释相关推荐

  1. scala 字符串转换数组_如何在Scala中将字节数组转换为字符串?

    scala 字符串转换数组 Byte Array in Scala is an array of elements of a byte type. String in Scala is a colle ...

  2. 如何将零终止的字节数组转换为字符串?

    本文翻译自:How to convert a zero-terminated byte array to string? I need to read [100]byte to transfer a ...

  3. 如何将字节数组转换为十六进制字符串,反之亦然?

    如何将字节数组转换为十六进制字符串,反之亦然? #1楼 在此不谈很多答案,但我发现十六进制字符串解析器的实现相当理想(比公认的要好约4.5倍),直接实现. 首先,我的测试输出(第一批是我的实现): G ...

  4. java 十六进制数组转字符串_Java通用将字节数组转换为字符串(非十六进制,十进制)...

    将字节数组转换为具有选择基数的字符串的最佳方法是什么? S.O上有大量示例.在其他地方转换为十六进制字符串.我主要感兴趣的是将其转换为十六进制或十进制字符串以外的内容:也是更通用的方式 这是我目前正在 ...

  5. 如何在Java中将字节数组转换为InputStream和OutputStream

    您是否坚持使用编码,因为您有字节数组,并且链中的下一个方法需要InputStream? 不用担心Java有解决方案,您可以使用 ByteArrayInputStream 在Java中将字节数组转换为I ...

  6. 字节数组转换为字符串

    1.字节数组转换为字符串 byte[] byBuffer = new byte[20]; ... ... String strRead = new String(byBuffer); strRead ...

  7. java中字节数组转换为字符串

    1.字节数组转换为字符串 byte[] byBuffer = new byte[20]; ... ... String strRead = new String(byBuffer); strRead= ...

  8. JavaScript:实现将字节数组转换为 base64 编码算法(附完整源码)

    JavaScript:实现将字节数组转换为 base64 编码算法 function bufferToBase64 (binaryData) {// The base64 encoding uses ...

  9. 如何将字节数组转换为字符串[duplicate]

    本文翻译自:How to convert byte array to string [duplicate] This question already has an answer here: 这个问题 ...

最新文章

  1. Linux下通过rm -f删除大量文件时提示-bash: /bin/rm: Argument list too long的解决方法...
  2. C语言接口的封装和设计专题
  3. 民生银行场景化数据中台是如何炼成的?
  4. [html] 举例说明写一个button的按钮的方法有哪些?
  5. 算法导论-用于不相交集合的数据结构
  6. 我的云之旅--hadoop单机设置(2)
  7. “这样使用RHEL合法吗”?
  8. 数据仓库分层设计思想
  9. 【万人千题】结对编程排位赛(第一期) 第一周 排名公布,这也太卷了
  10. 如何加载CASS DAT格式文件
  11. 如何用WPS表格生成拟合曲线
  12. TOF相机(Time of Fight Camera)(维基百科全翻译版)
  13. QQ群无法下载视频和图片解决方案
  14. printf颜色控制c语言,C语言中控制printf的打印颜色实例及vt100的控制符文档
  15. Java 第一章.基本语法
  16. 监听页面高度变化_js监听屏幕的高度变化
  17. 限流断路器与普通断路器的区别与联系
  18. CSM-客户成功经理的职责和价值
  19. 数商云S2B2C电商系统结算功能助力化工行业规避结算风险,提升结算管理能力
  20. Idea 中切换git分支

热门文章

  1. ORACLE 序列重置
  2. 离线存储及实例留言板
  3. 接口测试系列——转转交易业务场景接口测试实践
  4. ITN网络课程笔记(六)
  5. 集合中的数据存入到文件中,文件中的数据读取到集合中
  6. 重邮大学计算机基础考试试题及答案,计算机科学与技术学院重邮2007级数学大类专...
  7. Excel设置根据条件整行变色
  8. python123绘制五角星_Python的画五角星
  9. java中三角形面积和周长_java实现三角形面积和周长的计算
  10. 关于如何创业的书籍推荐