IO新手。。一个小问题,希望大虾们不吝赐教。。

结贴是美德 2012-01-02 01:37:34
我这有两个try块儿,都是试图读一个纯文本文件,然后再显示出来,文件里中英文全有。。文件时用UTF-8存的
第二个中文乱码。。。我貌似知道原因,但是呢,为何第一个全是乱码,难道DataInputStream的理解不到位?

先谢谢大家了~~

try {
DataInputStream in = new DataInputStream(
new FileInputStream(
"C:\\Users\\Dodolook\\Workspaces\\MyEclipse 10\\IO\\src\\iostream\\FormattedMemoryInput.java"));

while (true)
System.out.print(in.readChar());

} catch (EOFException e) {
System.err.println("End of stream");
}

try {
FileInputStream in = new FileInputStream(
"C:\\Users\\Dodolook\\Workspaces\\MyEclipse 10\\IO\\src\\iostream\\FormattedMemoryInput.java");

int i;
while ((i = in.read()) != -1)
System.out.print((char) i);

} catch (EOFException e) {
System.err.println("End of stream");
}
...全文
160 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
结贴是美德 2012-01-02
  • 打赏
  • 举报
回复
谢谢回答哈~~
貌似最后一句话看懂了。。
您的意思是 除非文件里的数据是用Unicode形式存储的,或者是用DataOutputStream输出的,DataInputStream都会读出乱码?

啊 那个~ 在没有nio之前 是怎么读出utf-8的数据的?
冰思雨 2012-01-02
  • 打赏
  • 举报
回复
哥,DataInputStream是用来读取Java元数据的。

首先,使用的类,不够正确。
如果要读取字符数据,那么,涉及到编码转换问题的,直接使用Reader的实现类,构造器中添加编码方式。
其次,不使用Reader实现类进行编码转换的,要进行手动转换。
UTF-8编码当中,英文字符和数字(ASCII编码范畴内的字节码)是用一个字节来表示一个字符的,
而汉字,一般都是三个字节来表示一个汉字字符,不会手动转码,出来的当然是乱码。
乱码是因为,程序无法按规定的转换规则进行转换。
最后,谈一下DataInputStream 类。
这个类,是用来从IO中读取Java元数据的,所谓的元数据,
就是Java的基本数据类型、原始数据类型,等等的例如int、long、boolean等的类型的数据。
使用DataOutputStream类,可以将这些元数据写入到IO中,
当然,这个过程中DataOutputStream类会完成元数据向二进制数据的转换(类似字符编码的转换,
但又不是)。所以,这时,写入后的数据,是有一定的结构的。
那么,使用DataInputStream 类,才能将这样结构的数据,读入到内存中,供程序来使用。
所以,这里的char和楼主文件里的字符,根本就是两个概念。

如果,还不理解我说的是什么,
我想,单独谈谈一个字符的表示。
一个字符(无论英文还是汉字还是外文)在JVM中都是采用Unicode编码形式来表示。
Unicode是双字节,定长编码。单个字符的编码长度,始终都是2个字节(16比特)。
而UTF-8编码,是变长编码,一个字符,根据字符的不同,可以用一个字节、两个字节、三个字节或四个字节表示。
GBK编码、GB2312编码,是变长编码,一个字符,如果是英文数字(ASCII编码内的字符)用一个字节表示;
如果是汉字字符,则用两个字节表示,为了区分一个字符和两个字节的编码形式,
规定,两个字节的表示中,每个字节的第一个(高位)比特必须为1.
这种编码方式是我们国家内定的汉字编码方式,当然,英文、数字也包含在内。

DataOutputStream(或DataInputStream)类,会直接将内存中的char数据(Unicode编码)直接写入到IO中(或从IO中直接读取两个字节当成Unicode编码的字符表示成char)
coooliang 2012-01-02
  • 打赏
  • 举报
回复
纯文件最好办了。

FileInputStream input = new FileInputStream("D:/workspace/CSDNTest/src/com/test/Test.java");
byte[] b = new byte[1024];
int len = 0;
while ((len = input.read(b)) != -1) {
System.out.print(new String(b,0,len));
}

使用bufferFileInputStream可以readLine()方法更快速。

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧