这段代码很简单,就是从一个文本文件读字节,然后转成String打印出来,public class TestStream {
public static void main(String[] args) throws Exception{
//q.txt带有中文和中文特有的标点符号。保存为ANSI编码格式
InputStream in = new FileInputStream("c:\\q.txt");
byte[] b = new byte[32];
int size = in.read(b);
while(size!=-1){
//下面这样会有很多乱码。
System.out.print(new String(b, 0, size));
//如果我把q.txt保存为UTF-8,然后象下面这样构造String, 乱码没了。
//但是有少量问号
//System.out.print(new String(b, 0, size, "UTF-8"));
size = in.read(b);
}
in.close();
}
}q.txt是一个简单的中文文本文件。比如:进行被过滤黑名单的更新
。同时会另外启用两个xnet2.ex
e线程,与211.161.1.134 和 203.171.
236.231进行通讯,后者ip为 河南郑州景安计算机网络 ,前者
是北京 长宽的一个ip,具体来源不明。
坝完美得全部符合。它的存在真的是为了保护未成人收到色情网站
的毒害吗?未必,监视大量应用程序,定时对系统进行截图,对代理软
件进行封锁,然后将用户电脑中的各种资料秘密传往某处。问题我已经描述在程序中了, 怎么可以消除这样的问题,
还有就是在像这样的InputStream中,我不知道那个文件保存为什么样的编码, 我要把它用流读出来,然后显示出来,怎么做才没有乱码。
不要告诉我用BufferedReader.
如果愿意就byte, char,字节流,字符流做一些讨论和指导更好。
谢谢热心的朋友们。
public static void main(String[] args) throws Exception{
//q.txt带有中文和中文特有的标点符号。保存为ANSI编码格式
InputStream in = new FileInputStream("c:\\q.txt");
byte[] b = new byte[32];
int size = in.read(b);
while(size!=-1){
//下面这样会有很多乱码。
System.out.print(new String(b, 0, size));
//如果我把q.txt保存为UTF-8,然后象下面这样构造String, 乱码没了。
//但是有少量问号
//System.out.print(new String(b, 0, size, "UTF-8"));
size = in.read(b);
}
in.close();
}
}q.txt是一个简单的中文文本文件。比如:进行被过滤黑名单的更新
。同时会另外启用两个xnet2.ex
e线程,与211.161.1.134 和 203.171.
236.231进行通讯,后者ip为 河南郑州景安计算机网络 ,前者
是北京 长宽的一个ip,具体来源不明。
坝完美得全部符合。它的存在真的是为了保护未成人收到色情网站
的毒害吗?未必,监视大量应用程序,定时对系统进行截图,对代理软
件进行封锁,然后将用户电脑中的各种资料秘密传往某处。问题我已经描述在程序中了, 怎么可以消除这样的问题,
还有就是在像这样的InputStream中,我不知道那个文件保存为什么样的编码, 我要把它用流读出来,然后显示出来,怎么做才没有乱码。
不要告诉我用BufferedReader.
如果愿意就byte, char,字节流,字符流做一些讨论和指导更好。
谢谢热心的朋友们。
楼主的问题,其实又回到了JDK的早期了:即只有字符流,怎样正确回到字符流?
正常做法:
1)字节流读取BOM,若有则按BOM的编码进行字符流的解析。
2)若没有BOM,则只能猜测字节流是什么字符编码了(GBK?GB2312-80?等等),WIN下的WORD直到现在还是这样嘛“若无BOM,则询问使用者:文件是何编码?(默认是平台的默认编码:WIN是GBK,LINUX下是UTF-8)
3)只有知道了编码,才好用桥类InputStreamReader进行最后的字符解码的读取。
http://topic.csdn.net/u/20090625/22/59a5bfc8-a6b6-445d-9829-ea6d462a4fe6.html?seed=1942058963
有可能第size与size+1之间才能构成一个字符,若这样就分柝了,会有乱码的。
是不是说ANSI编码的话,有一些字符占一个字节,(像ascii范围内的) 有的占用2个?(像汉字)
public class TestStream {
public static void main(String[] args) throws Exception{
//q.txt带有中文和中文特有的标点符号。保存为ANSI编码格式
InputStream in = new FileInputStream("c:\\q.txt");
byte[] b = new byte[640]; int size = in.read(b);
BufferedOutputStream bos=new BufferedOutputStream(System.out);
while(size!=-1){
//下面这样会有很多乱码。
System.out.print(new String(b, 0, size));
//如果我把q.txt保存为UTF-8,然后象下面这样构造String, 乱码没了。
//但是有少量问号
//System.out.print(new String(b, 0, size, "UTF-8"));
//bos.write(b,0,32);
size = in.read(b);
}
in.close();
}
总结一下吧
1. 如果用字节流不包装的话,又不知道对方的编码,是没有办法的,只能按规律来
2. LZ有的解出是问好的,估计是拆分了字符导致的,和System.out.print(new String(b, 0, size));有关系
解决的办法是可以整文读取,放到内存,但是这样如果文件很大,会不会好呢,会不会有其它的办法呢,关注!!
3. 其实现在的jdk已经针对以前字节流的不足,补充了很多包装类,LZ应该针对不同的应用环境来选择使用的
* Title: CatchFileEncoding.java<br>
* Description:获取文件字符集<br>
* Copyright @ 2006 .All rights reserved.<br>
* @author LiN
* @version 2009-2-4 1.0
*/
public class CatchFileEncoding { private static void test(InputStream is) throws IOException{
BufferedInputStream bis = new BufferedInputStream(is);
BufferedReader br = null;
byte[] fileHead = new byte[3];
try {
bis.(0);
bis.read(fileHead, 0, fileHead.length);
bis.reset();
if(checkEncoding(fileHead)==1){
br = new BufferedReader(new InputStreamReader(bis,"UTF-8"));
}
// JDK5好像没有支持Unicode的Charset
// else if(checkEncoding(fileHead)==2){
// br = new BufferedReader(new InputStreamReader(bis,"UNICODE-1-1"));
// }
else{
br = new BufferedReader(new InputStreamReader(bis));
}
System.out.println(br.readLine());
} catch (IOException e) {
e.printStackTrace();
}finally{
br.close();
}
for(int i=0;i<fileHead.length;i++){
System.out.print(fileHead[i] + " ");
}
// String line = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(fileHead))).readLine();
// System.out.println(line);
System.out.println();
}
//利用读取文件前3个字节判断是否为UTF-8字符集(-17-69-65)(0xEF,0xBB,0xBF)
//Unicode(-1 -2)(0xFF 0xFE)
private static int checkEncoding(byte[] fileHead){
final int UTF_8 = 1;
final int UNICODE = 2;
final int DEFAULT_ENCODING = 3;
if(fileHead==null || fileHead.length<3)
throw new RuntimeException("exception");//这里可抛出数据体不完整异常
if((fileHead[0] & 0xFF)==0xEF && (fileHead[1] & 0xFF)==0xBB && (fileHead[2] & 0xFF)==0xBF)
return UTF_8;
if((fileHead[0] & 0xFF)==0xFF && (fileHead[1] & 0xFF)==0xFE)
return UNICODE;
return DEFAULT_ENCODING;
}
public static void main(String[] args) throws IOException {
//System.out.println(Charset.availableCharsets());
String[] txtFileNameArray = new File(CacheFileEncoding.class.getResource("").getPath()).list(new FilenameFilter(){
public boolean accept(File dir, String name) {
if("txt".equals(name.split("\\.")[1]))
return true;
return false;
}
});
for(int i=0;i<txtFileNameArray.length;i++){
System.out.print(txtFileNameArray[i] + "-->");
test(CacheFileEncoding.class.getResourceAsStream(txtFileNameArray[i]));
System.out.println();
}
}
}
InputStreamReader read = new InputStreamReader("c:\\q.txt");
BufferedReader br = new BufferedReader(read);
出现了问题,因为你每次读取的是32个字节,导致错误,我换了输出:发现如下:32
进行被过滤黑名单的更新。同时会另
32
外启用两个xnet2.exe线程,与211.1
32
61.1.134 和 203.171.236.231进行?//这一行导致通讯的“通”字出现了问题,所以出现了乱码
32
ㄑ叮笳遡p为 河南郑州景安计算机
32
网络 ,前者是北京 长宽的一个ip?
32
咛謇丛床幻鳌0油昝赖萌糠稀
32
K拇嬖谡娴氖俏吮;の闯扇耸盏
32
缴橥镜亩竞β穑课幢兀嗍哟罅
32
坑τ贸绦颍ㄊ倍韵低辰薪赝迹
32
源砣砑蟹馑缓蠼没У缒
29
灾械母髦肿柿厦孛艽炒Α?-1
楼主说"不要告诉我用BufferedReader. " 是撒意思啊?
貌似像是接触字符编码处理时间比较短暂。一般情况下,我们就用固定编码形式来处理字节流。
如果发现乱码,就更改配置文件,换一个编码试一试。如果,程序非要完成编码的自动识别。这个问题就非常有难度了。
通常的办法,就是逐个的将已知的编码逐个去试,能解码成功的就OK。
这方面做的比较好的,mozilla基金会有一个Firefox用来自动探测编码的库
LZ可以参看一下它的使用方式。
其他方面的我就不知道了。我一般遇到这种情况,都是按照固定编码的方式来做的。
只是,先使用GBK解码试试,不行再换UTF-8试试,都不行,就程序停止。
InputStream is = ....;
InputStreamReader isr = new InputStreamReader(is,"GBK");
如果代码有异常,就重新获取InputStream , 然后InputStreamReader isr = new InputStreamReader(is,"UTF-8");
当然,如果无法重新获取InputStream 的情况下,
貌似有个ByteArrayInputStream的类,可以先把字节流存到这里,然后再使用。
因为写一段代码引起了我对编码和字符集的兴趣。
http://blog.csdn.net/sunxing007/archive/2009/06/29/4305956.aspx
这篇文章中, 解析http头需要用字节流,但是http头是有含义的,所以要把读到的http头的一行转换为字符串。
于是我想顺便探讨一下子节流转字符流的问题。