`
my_java_life
  • 浏览: 145130 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

java读写编码解惑(转)

 
阅读更多

最近在处理文件时发现了同样类型的文件使用的编码可能是不同的。所以想将文件的格式统一一下(因为UTF-8的通用性,决定往UTF-8统一),遇见的第一个问题是:如何查看现有文件的编码方式。

上网找了一下,找到几篇比较好文章,这里就不转载啦把链接搞过来。
文件编码问题集锦
字符串编码(charset,encoding,decoding)问题原理
Java编码浅析
判定文件编码或文本流编码的方法
上面的几篇文章可以看成认识编码问题的“从入门到精通”

如果你看完了上面的文章,一定了解到了,在java中,class文件采用utf8的编码方式,JVM运行时采用utf16。Java的字符串是永远都是unicode的,采用的是UTF-16的编码方式。

想测试一下,java对UTF-8文件的读写的能力,结果发现了一个很郁闷的问题,如果通过java写的UTF-8文件,使用Java可以正确的读,但是如果用记事本将相同的内容使用UTF-8格式保存,则在使用程序读取是会从文件中多读出一个不可见字符。
测试代码如下:

Java代码  收藏代码
  1. import  java.io.BufferedReader;  
  2. import  java.io.File;  
  3. import  java.io.FileInputStream;  
  4. import  java.io.IOException;  
  5. import  java.io.InputStreamReader;  
  6.   
  7.   
  8. public   class  UTF8Test {  
  9.     public   static   void  main(String[] args)  throws  IOException {  
  10.         File f  = new  File( "./utf.txt" );  
  11.         FileInputStream in = new  FileInputStream(f);  
  12.         // 指定读取文件时以UTF-8的格式读取   
  13.         BufferedReader br = new  BufferedReader( new  InputStreamReader(in,  "UTF-8" ));  
  14.           
  15.         String line = br.readLine();  
  16.         while (line !=  null )  
  17.         {  
  18.             System.out.println(line);  
  19.             line = br.readLine();  
  20.         }  
  21.     }  
  22. }  



utf.txt通过记事本创建,另存时使用指定utf-8编码,其内容为:

引用

This is the first line.
This is second line.



正常的测试结果应该是直接输出utf.txt的文本内容。可是实际上却输出了下面的内容:

引用

?This is the first line.
This is second line.


第一行多出了一个问号。
通过上面的几篇文章应该可以想到是Java读取BOM(Byte Order Mark)的问题,在使用UTF-8时,可以在文件的开始使用3个字节的"EF BB BF"来标识文件使用了UTF-8的编码,当然也可以不用这个3个字节。
上面的问题应该就是因为对开头3个字节的读取导致的。开始不太相信这个是JDK的Bug,后来在多次试验后,问题依然存在,就又狗狗了一下,果然找到一个如下的Bug:
Bug ID:4508058
不过在我关掉的一些页面中记得有篇文件说这个bug只在jdk1.5及之前的版本才有,说是1.6已经解决了,从目前来看1.6只是解决了读取带有BOM 文件失败的问题,还是不能区别处理有BOM和无BOM的UTF-8编码的文件,从Bug ID:4508058里的描述可以看出,这个问题将作为一个不会修改的问题关闭,对于BOM编码的识别将由应用程序自己来处理,原因可从另处一个bug处 查看到,因为Unicode对于BOM的编码的规定可能发生变化。也就是说对于一个UTF-8的文件,应用程序需要知道这个文件有没有写BOM,然后自己 决定处理BOM的方式。

在上面的while循环中可加入下面的代码,测试一下读出内容:

Java代码  收藏代码
  1. byte [] allbytes = line.getBytes( "UTF-8" );   
  2.             for  ( int  i= 0 ; i < allbytes.length; i++)  
  3.             {  
  4.                 int  tmp = allbytes[i];  
  5.                 String hexString = Integer.toHexString(tmp);  
  6.                 // 1个byte变成16进制的,只需要2位就可以表示了,取后面两位,去掉前面的符号填充   
  7.                 hexString = hexString.substring(hexString.length() -2 );  
  8.                 System.out.print(hexString.toUpperCase());  
  9.                 System.out.print(" " );  
  10.             }  



输出结果如下:

引用

EF BB BF 54 68 69 73 20 69 73 20 74 68 65 20 66 69 72 73 74 20 6C 69 6E 65 2E
?This is the first line.
54 68 69 73 20 69 73 20 73 65 63 6F 6E 64 20 6C 69 6E 65 2E
This is second line.


红色部分的"EF BB BF"刚好是UTF-8文件的BOM编码,可以看出Java在读文件时没能正确处理UTF-8文件的BOM编码,将前3个字节当作文本内容来处理了。

使用链接中提供的代码可以解决碰到的乱码问题:
http://koti.mbnet.fi/akini/java/unicodereader/

修改测试代码中的输入流后:

Java代码  收藏代码
  1. BufferedReader br =  new  BufferedReader( new  UnicodeReader(in, Charset.defaultCharset().name()));  


执行,可以看到正确的结果。

将用到的测试代码及UTF-8读取乱码解决(http://koti.mbnet.fi/akini/java/unicodereader)的源码放在了附件中

 

 

编码一直在困扰着我,这边文章比较经典,情不自禁(转)了:

转自:http://daimojingdeyu.iteye.com/blog/397661

分享到:
评论

相关推荐

    java解惑java解惑java解惑

    "Java解惑"这个主题,显然旨在帮助开发者解决他们在学习和实践中遇到的问题。在Java的世界里,疑惑可能涵盖语法、类库、框架、并发、内存管理等多个方面。下面,我们将深入探讨一些常见的Java解惑知识点。 1. **...

    java_各种编码转换源代码

    在Java编程语言中,编码转换是一项重要的任务,特别是在处理不同来源的数据时,如读取文本文件、网络数据传输或数据库交互。...通过深入研究和实践,可以增强对Java编码转换机制的理解,提升软件质量。

    java文件的编码转换

    本文将深入探讨“Java文件的编码转换”这一主题,以及如何利用Java来解决由于不同编码格式引起的兼容性问题。 首先,我们需要理解什么是文件编码。文件编码是指在计算机中存储和处理文本的方式,常见的有GBK和UTF-8...

    java中编码的转换

    在Java编程环境中,字符...总结来说,Java中字符编码的处理涉及多个层面,包括数据库连接、网页编码声明、文件读写等。通过正确配置和编码转换,可以有效解决中文显示问题,确保应用程序在不同编码环境下均能正常运行。

    原生JAVA读写PLC

    本教程将聚焦于如何使用原生Java 8来实现对西门子S7系列PLC的读写操作,而无需依赖任何DLL(动态链接库)文件,确保了程序的平台独立性和纯粹性。 首先,我们要理解S7协议。西门子的S7协议是用于其PLC产品通信的一...

    java 读写锁代码

    Java 读写锁是Java并发编程中的一种重要机制,它为多线程环境下的数据访问提供了更为精细的控制。在Java的`java.util.concurrent.locks`包中,`ReentrantReadWriteLock`类实现了读写锁的功能。这个锁允许多个读取者...

    关于java中的编码转换问题(解决乱码问题)

    Java的`FileInputStream`和`FileOutputStream`在读写文件时默认使用平台的默认编码。要指定特定编码,可使用`InputStreamReader`和`OutputStreamWriter`,如`new InputStreamReader(fileInputStream, "UTF-8")`。 ...

    java批量转换文件编码

    总结来说,Java提供了一种有效的方法来批量转换文件编码,只需指定文件路径、编码类型以及适当的读写工具。这使得开发者能够轻松地在不同的编码格式之间切换,确保数据在各种系统和环境下的兼容性。在实际项目中,...

    java读写hdf5格式文件需要使用的库

    这里提供的jar文件`hdf5-3.3.2.jar`是Java接口库,它封装了对HDF5文件的操作,使得Java程序员可以通过调用Java API来实现读写HDF5文件。而`libjhdf.so.3.2.1`和`jhdf5.dll`分别是Linux和Windows平台的动态链接库,...

    java读写Modbus TCP UDP数据,java与modbus通信,Modbus TCP UDP与java通信 全开源

    java读写Modbus TCP UDP数据,java与modbus通信,Modbus TCP UDP与java通信 全开源 这是一个能正常通过Modbus TCP UDP协议读写项目 请放心下载,完全开源,在多个项目中已经使用

    Java读写文件(excel)

    Java读写文件-Excel

    java文件读写操作大全java文件读写操作大全

    Java 文件读写操作大全 Java 文件读写操作大全是 Java 语言中对文件进行读写操作的详细介绍。下面将对 Java 文件读写操作大全中的知识点进行详细解释。 一、获得控制台用户输入的信息 Java 中可以使用 `System.in...

    JAVA 转换字符编码工具

    在处理文件时,如果不指定编码,Java会使用平台默认的编码,这可能导致在不同平台上读写文件时出现乱码问题。因此,`ReadFile.java`这个源码文件很可能包含了读取文件时指定编码的逻辑。例如,使用`BufferedReader`...

    java读写Modbus RTU数据,java串口modbus通信,Modbus RTU与java通信 全开源

    最近在研究处理java写modbus RTU通信,分别使用几套工具,模拟modbus从站、模拟串口等才能正常在电脑测试成功。 全开源,放心下载 可以查看运行内容https://blog.csdn.net/weijia3624/article/details/121216539

    java 读写文本的方法

    在Java编程语言中,读写文本文件是常见的操作。这里我们详细探讨了四种不同方法来读取文本文件:按字节读取、按字符读取、按行读取以及随机读取。 1. **按字节读取文件内容**: 这种方法通常适用于读取二进制文件...

    JAVA文件编码转换

    `Charset`可以用来编码(字符串转字节)和解码(字节转字符串)。Java默认支持多种常见的字符集,如ASCII、UTF-8、GBK等。 #### 文件读写操作 在Java中,读取和写入文件通常有两种方式:流式操作(使用`...

    Java读写Yaml文件的工具类-snakeyaml

    java通过snakeyaml类能非常方便的操作,读写yaml文件。

    Java字符编码转换过程说明

    Java字符编码转换是Java开发中一个重要的概念,涉及到数据的正确读取、存储和传输。在Java中,编码转换通常发生在以下几个场景: 1. **JVM启动与系统属性**: JVM启动时,会根据操作系统的环境设置一些系统属性,...

    Java 读写docx文件后直接转成PDF方法

    1. **Java I/O流**:在读写文件时,Java的I/O流扮演着核心角色。`java.io`包提供了多种类,如`FileInputStream`用于读取文件,`FileOutputStream`用于写入文件。在处理docx到PDF转换时,你需要先读取docx文件的内容...

    java读写pdf文件,教程文档与实例

    java读写pdf文件,教程文档都有,用读写pdf文件的方式做表格显示与打印效果很不错

Global site tag (gtag.js) - Google Analytics