io读文件显示在控制台问题汇总
2016-07-15 22:38
363 查看
今天回顾并手写了一个读文件并显示在控制台上的代码,如下:
test.txt文件原内容如下(随机内容,以UTF-8保存):
一,首先想到比较一下read()和read(byte[] b)的区别
根据api帮助文档加上些许个人理解,
read()从输入流中读取数据的下一个字节,返回0到255范围内的int字节值。如果因为已经到达流末尾而没有可用的字节,则返回-1。在输入数据可用、检测到流末尾或者抛出异常前,此方法一直阻塞。
read(byte[] b)从输入流中读取一定数量的字节,并将其存储在缓冲区数组 b 中。以整数形式返回实际读取的字节数。在输入数据可用、检测到文件末尾或者抛出异常前,此方法一直阻塞。如果 b 的长度为 0,则不读取任何字节并返回 0;否则,尝试读取至少一个字节。如果因为流位于文件末尾而没有可用的字节,则返回值 -1;否则,至少读取一个字节并将其存储在 b 中。将读取的第一个字节存储在元素 b[0] 中,下一个存储在 b[1] 中,依次类推。读取的字节数最多等于 b 的长度。
读取文档如果用read()来写的话,需要每个字节强转为相应char类型,但是读取出来的汉字肯定就是乱码了,因为char只能一个字节一个字节读,读取英文还是可以的。
二,问题1,出现全部乱码
1.上面代码运行结果如图:
这是因为在java中,class文件采用utf8的编码方式,JVM运行时采用utf16。Java的字符串是永远都是unicode的,采用的是UTF-16的编码方式,我理解,也就是所谓的解错码。
要解决这一问题需要使用外部资源采用的字符集来读取外部数据,改进代码如下:
主要起作用的是Reader reader = new InputStreamReader(inputStream, “UTF-8”);
这一句使用外部资源的字符集也就是UTF-8来进行读文件,从而能够以正确方式转化。
三,问题2,控制台输出出现首字符问号的问题
上面代码运行结果如下:
对于这一点我十分疑惑,花费了很长时间在网上查找资料,最终这篇博客对我帮助很大,而且这篇博客写的非常充实、资料也很丰富,对于解决乱码问题有很好的帮助:
解决乱码问题的博客
从这篇博客得知,这是因为文本BOM(Byte Order Mark)的机制,带有BOM的UTF-8文本首三个字节为EF BB BF ,而JDK一直存在一个BUG,那就是无法识别前三个字节把他们也当作文本内容读取了,该BUG为:
Bug ID:4508058
可以从描述看出,这个问题将作为一个不会修改的问题关闭,对于BOM编码的识别将由应用程序自己来处理,原因可从另处一个bug处查看到,因为Unicode对于BOM的编码的规定可能发生变化。也就是说对于一个UTF-8的文件,应用程序需要知道这个文件有没有写BOM,然后自己决定处理BOM的方式。
我将test.txt文件用Editplus打开,用十六进制查看器看到:
首三个字节的确是EF BB BF。
我将test.txt文件用去掉BOM的UTF-8保存,并用十六进制查看器看到:
的确是去掉了首三个字节。
运行结果如下:
经过千辛万苦,终于去掉了所有乱码,但是我这只是修改了我文件的保存方式,这篇博客中也提到了对于带BOM的文件解决办法:
http://koti.mbnet.fi/akini/java/unicodereader/
在这里我也附上里面所提到的解决乱码问题非常好的几篇文章,亲测的确很有帮助:
文件编码问题集锦
字符串编码(charset,encoding,decoding)问题原理
Java编码浅析
判定文件编码或文本流编码的方法
四,问题3,回车换行没有读出来
细心的小伙伴们都发现了,控制台上显示出来的跟文件相比,回车换行并没有读出来,这个问题我也找到了解决办法,通过 commons-io-*.jar 。
代码如下:
运行结果:
Apache 的io工具包非常简便,好用,可以直接解决换行没读的问题,但是我测试了一下,首字符为问号的问题依然没有解决。
Apache的io工具包使用简例
import java.io.*; public class ioTest { public static void main(String[] args){ String path = "G:/javaworkspace/Test/io/src/"; File file = new File(path + "test.txt"); InputStream inputStream = null; int i=0; try { inputStream = new FileInputStream(file); byte[] bytes = new byte[16]; while ((i = inputStream.read(bytes))!=-1){ String str = new String(bytes); System.out.print(str); } }catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }
test.txt文件原内容如下(随机内容,以UTF-8保存):
一,首先想到比较一下read()和read(byte[] b)的区别
根据api帮助文档加上些许个人理解,
read()从输入流中读取数据的下一个字节,返回0到255范围内的int字节值。如果因为已经到达流末尾而没有可用的字节,则返回-1。在输入数据可用、检测到流末尾或者抛出异常前,此方法一直阻塞。
read(byte[] b)从输入流中读取一定数量的字节,并将其存储在缓冲区数组 b 中。以整数形式返回实际读取的字节数。在输入数据可用、检测到文件末尾或者抛出异常前,此方法一直阻塞。如果 b 的长度为 0,则不读取任何字节并返回 0;否则,尝试读取至少一个字节。如果因为流位于文件末尾而没有可用的字节,则返回值 -1;否则,至少读取一个字节并将其存储在 b 中。将读取的第一个字节存储在元素 b[0] 中,下一个存储在 b[1] 中,依次类推。读取的字节数最多等于 b 的长度。
读取文档如果用read()来写的话,需要每个字节强转为相应char类型,但是读取出来的汉字肯定就是乱码了,因为char只能一个字节一个字节读,读取英文还是可以的。
二,问题1,出现全部乱码
1.上面代码运行结果如图:
这是因为在java中,class文件采用utf8的编码方式,JVM运行时采用utf16。Java的字符串是永远都是unicode的,采用的是UTF-16的编码方式,我理解,也就是所谓的解错码。
要解决这一问题需要使用外部资源采用的字符集来读取外部数据,改进代码如下:
import java.io.*; public class ioTest2 { public static void main(String[] args) { String path = "G:/javaworkspace/Test/io/src/"; File file = new File(path + "test.txt"); InputStream in = null; String line; StringBuffer sb = new StringBuffer(); try { in = new FileInputStream(file); Reader reader = new InputStreamReader(in, "UTF-8"); //创建使用指定字符集的 InputStreamReader //增加缓冲功能,提高效率 BufferedReader br = new BufferedReader(reader); while ((line = br.readLine()) != null) { sb.append(line); } if (br != null) { br.close(); } String content = sb.toString(); System.out.print(content); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }
主要起作用的是Reader reader = new InputStreamReader(inputStream, “UTF-8”);
这一句使用外部资源的字符集也就是UTF-8来进行读文件,从而能够以正确方式转化。
三,问题2,控制台输出出现首字符问号的问题
上面代码运行结果如下:
对于这一点我十分疑惑,花费了很长时间在网上查找资料,最终这篇博客对我帮助很大,而且这篇博客写的非常充实、资料也很丰富,对于解决乱码问题有很好的帮助:
解决乱码问题的博客
从这篇博客得知,这是因为文本BOM(Byte Order Mark)的机制,带有BOM的UTF-8文本首三个字节为EF BB BF ,而JDK一直存在一个BUG,那就是无法识别前三个字节把他们也当作文本内容读取了,该BUG为:
Bug ID:4508058
可以从描述看出,这个问题将作为一个不会修改的问题关闭,对于BOM编码的识别将由应用程序自己来处理,原因可从另处一个bug处查看到,因为Unicode对于BOM的编码的规定可能发生变化。也就是说对于一个UTF-8的文件,应用程序需要知道这个文件有没有写BOM,然后自己决定处理BOM的方式。
我将test.txt文件用Editplus打开,用十六进制查看器看到:
首三个字节的确是EF BB BF。
我将test.txt文件用去掉BOM的UTF-8保存,并用十六进制查看器看到:
的确是去掉了首三个字节。
运行结果如下:
经过千辛万苦,终于去掉了所有乱码,但是我这只是修改了我文件的保存方式,这篇博客中也提到了对于带BOM的文件解决办法:
http://koti.mbnet.fi/akini/java/unicodereader/
在这里我也附上里面所提到的解决乱码问题非常好的几篇文章,亲测的确很有帮助:
文件编码问题集锦
字符串编码(charset,encoding,decoding)问题原理
Java编码浅析
判定文件编码或文本流编码的方法
四,问题3,回车换行没有读出来
细心的小伙伴们都发现了,控制台上显示出来的跟文件相比,回车换行并没有读出来,这个问题我也找到了解决办法,通过 commons-io-*.jar 。
代码如下:
import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.util.List; import org.apache.commons.io.FileUtils; public class commonsIOTest{ public static void main(String[] args) { String path = "G:/javaworkspace/Test/io/src/"; File file = new File(path + "test.txt"); try { //方法1 String content = FileUtils.readFileToString(file,"UTF-8"); System.out.println(content); //方法2 List<String> contents = FileUtils.readLines(file,"UTF-8"); for (String string : contents) { System.out.println(string); } } catch (FileNotFoundException e) { e.printStackTrace(); }catch (IOException e) { e.printStackTrace(); } } }
运行结果:
Apache 的io工具包非常简便,好用,可以直接解决换行没读的问题,但是我测试了一下,首字符为问号的问题依然没有解决。
Apache的io工具包使用简例
相关文章推荐
- Orace查询数据出现乱码的问题解决思路
- oracle em 按钮乱码解决办法及em网页变成英文
- C#读取中文文件出现乱码的解决方法
- mysql命令提示行连接乱码的解决
- 解决Java程序使用MySQL时返回参数为乱码的示例教程
- 完美解决SQL server2005中插入汉字变成问号的问题
- Jquery乱码的一次解决过程 图解教程
- Mysql IO 内存方面的优化
- 解决realplayer11中文正式版网页右键乱码问题embed_cn.dll
- 计算机中的字符串编码、乱码、BOM等问题详解
- PHP附件下载中文名称乱码的解决方法
- PHP使用PDO操作数据库的乱码问题解决方法
- C# 运算符 ?、??、?: 各种问号的用法和说明
- php+AJAX传送中文会导致乱码的问题的解决方法
- Discuz!nt 源文件变成乱码的解决方法
- 关于backbone url请求中参数带有中文存入数据库是乱码的快速解决办法
- jQuery调用AJAX时Get和post公用的乱码解决方法实例说明
- JavaScript中出现乱码的处理心得
- Js,alert出现乱码问题的解决方法
- 深入Lumisoft.NET组件开发碰到乱码等问题的解决方法