日期:2014-05-20  浏览次数:20637 次

读取本文部分数据变为byte数组,如何防止字符被拆开?
如题。具体情形是:我要读取一个大文本,于是每次读取一小部分(假设每次读取58kb),读取出来的形式是byte数组,然后再把byte数组转化为String。现在遇上的问题是一些特殊编码如unicode最开始读取到的58kb数据不是乱码,但是往后都是乱码了。经过查找资料得知,原因是unicode一个字符要占几个字节吧,由于我分块读取所以把分界点的字符拆开了,比如只读取了半个字符。应该这就是问题所在了吧。现在我考虑的办法是分析每块读取的byte数组最后长度为10的一部分如果没有半个字符就读完,如果有半个字符就归到下一块。只是我不知该如何区分,求助。或者你们觉得我的想法有错或者有更好的想法也可以提出来。编码类型现在考虑到的有UNICODE、UTF-16BE、UTF-16LE。值得注意的是现在我已经能判断这几种编码类型了,所以问题仅仅有以上所说的

------解决方案--------------------
这种读取方法太繁琐了。
------解决方案--------------------
你对文件操作的根本目的是什么?
如果可能,使用nio方便多了
------解决方案--------------------
分析每块读取的byte数组最后长度为10的一部分如果没有半个字符就读完,如果有半个字符就归到下一块。
你得这种方法可能只能自己从底层编代码实现。

非得读取出来的形式是byte数组吗?
例如用BufferedReader.read(char[], int, int)方法读入到char数组不会出现“半个汉字”的问题。但是要自己控制读取的长度(比如58k)。

如果不是一定要读取出到byte数组,用读入字符的方式,处理中西文混排的文本时不会有“半个汉字”的问题。
------解决方案--------------------
探讨
如果有半个字符就归到下一块。只是我不知该如何区分,

------解决方案--------------------
直接用字符流不就好了吗?如果你知道是utf8的话。
http://docs.oracle.com/javase/tutorial/i18n/text/stream.html
------解决方案--------------------
探讨

char数组也可以但是我不懂怎么把char数组指定编码变为String
还有就是英文unicode编码的也会出现乱码

------解决方案--------------------
探讨
如题。具体情形是:我要读取一个大文本,于是每次读取一小部分(假设每次读取58kb),读取出来的形式是byte数组,然后再把byte数组转化为String。现在遇上的问题是一些特殊编码如unicode最开始读取到的58kb数据不是乱码,但是往后都是乱码了。经过查找资料得知,原因是unicode一个字符要占几个字节吧,由于我分块读取所以把分界点的字符拆开了,比如只读取了半个字符。应该这就是问题所在了吧……

------解决方案--------------------
文本读取就不应该是byte[]数组了
而是char[]
InputStream实现用BufferedInputStream

char[] -> String和byte没区别
String的构造函数有
String(char[],offset,size)
------解决方案--------------------
如果只是你顶楼提到的那几种编码,它们有个特点就是总是偶数字节编码的(不论中英文),
所以只要你的切块是偶数字节大小,不可能有字符断在切块之间。

------解决方案--------------------
如果再考虑GB和UTF-8,那就难了。
这种情况下,
理论上你从文章中间找10个连续字节,判断出正确字符起点的可能性不大。

abcdefghij
可能ab cd ef gh ij是合法字符的同时bc de fg hi也是合法字符。

这时,只有两个办法:
①从10个字节增加到1000个字节(举例),增加准确度,但依然不可能达到100%正确
②从前往后依次读取(也就是说,知道正确字符起点,仅需剔除结尾残字到下一块)但似乎不符合你的需求
------解决方案--------------------
探讨

比如 有个高手说 根据码头和编码类型可以确定多少个字节为一个字符

------解决方案--------------------
探讨

不错啊。记得测试下每种charset下不同的换行符字节序列啊,免得破坏换行符。
还有考虑不同OS上的换行符不同的问题。

------解决方案--------------------
探讨
我就是用nio 内存映射 我读取的是1Gb的文本 请大家不要管其他事了 这样子做都是别人的特殊要求你们自己当然不能理解了 因为你们不是本人 请帮一下忙

------解决方案--------------------
探讨

feff前缀是啥意思


------解决方案--------------------
11楼的代码不能实现你的需求吗?

建议你停下来去看看JDK源码,你会发现读取不同字符集的文件是怎么实现的。

你似乎很执着,非得读到byte[]检测“半个字符”之类。先前我在7L说了,按你的思路,要自己编写代码从底层实现,例如你读入58K到byte[],得从byte[]起始处检测,其实JDK现成的方法也是这么干的,你这么绕来绕去的,何不直接用它给你提供的现成的方法呢?

涉及这些比较底层的东西,停下来去看看JDK相应的源码比较好。如果你不能确保写出比它更好的实现代码,还是用它给你提供的现成的方法比较好一点。