`
cii001
  • 浏览: 24362 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

判断文件的编码是否是UTF-8(zhuan)

阅读更多

这里研究一下如何来判断文件的编码是否是 UTF-8, 关于这个问题网络上一般采用的是判断文件的 BOM 头,但是这种方法有个缺 点,就是有一些工具,比如 EditPlus, 比如 Java 程序,做出来的 UTF-8 编码的文件是不会在文件内 容的前面加上 BOM 头的,对于这种情况,网络上的这个办法就会检测失败。

 

在经过一些测试之后,研究了一个解决方案。

 

考虑如下文件输入流的代码,

 

FileInputStream fis = null ;

InputStreamReader isr = null ;

BufferedReader br = null ;

            

            

File f = new File(fn);

fis = new FileInputStream(f);

isr = new InputStreamReader(fis, "UTF-8" );

br = new BufferedReader(isr);

 

推测执行原理如下,(都是根据测试结果的猜测)

 

1。fis 根据文件的保存编码来采用不同的编码读取文件。读取结果为byte[]

2.isr设定的话,那么根据isr设定的编码来读取文件,如果不设定,那么编码采用系统默认编码 ansi(window-31j,shift_jis)

3。br.readline,将isr的结果组合为String,如果isr没有设定编码,那么组合 String时采用的编码为系统默认编码 ansi(window-31j,shift_jis),如果isr设定了编码,那么采用isr设定好的编码。

4。new string(byte[],"encode")  根 据指定编码生成string,如果不指定,采用系统默认编码。系统默认编码 ansi

5。string.getbyte("encode")   从 String根据特定的编码取得byte[]

 

问题出在第 1 步, 第一步 fis 因为读取文件的时候,调用的是 native ,也就是系统( windows 系统)的东西,他用了系统的东西, 系统的这个东西作了编码判断,但是因为他调用的是 native 的 东西,这个判定结果没有返回给 java ,导致 java 里面 isr,br 没有办法跟 fis 协调一致, isr,br 只能采用系统默认编码 ansi(window-31j,shift_jis) ,而不是采用 fis 的判定结果来读取文件。

 

 

这导致了,当文件使用 ansi 编 码保存的时候,默认编码跟 fis 判定结果一致,不会出任何问题。

 

当文件使用了 utf-8 编 码的时候,默认编码 ansi, fis 判定结果 utf-8 不一致, fis 采用 uft-8 编码读取出文件内容,而后, br.readline 采用系统默认编码把 UTF-8 编码对应的 byte[] 组合成了 ansi 编码对应的字符串,就产生了乱码。

 

 

我在网络以及 java api 里 面查找了一下,没有找到判定文件保存编码的方法。推论:因为 java 是 调用了 native 的方法来实际读取文件的,判定在 native 里面完成,但是没有把判定结果公开给我们程序员。

 

另有一个测试结果的推论,英文字符在任何编码下面读取出来的 byte[] 都是一样的。因为我们才用任何编码都不会出现英文字符乱码的问题,所以大多数时候这个判定对我们没有影响,这里不讨论特殊情况 下因为这个原因造成的影响。

  

 

根据以上推论,考虑如下解决问题的思路,

 

1 。通过 fis 来读取文件,这个时候读取来的 byte[] 根 据文件的保存格式是不同的。 fis 会自动判断处理。

2 。通过 br 来读取文件。代码示例如下:

private static void readTest(String fn){

         BufferedReader br = null ;

         InputStreamReader isr = null ;

         FileInputStream fis = null ;

         try {

                 File f = new File(fn);

                 fis = new FileInputStream(f);

                 isr = new InputStreamReader(fis, "UTF-8" );

                 br = new BufferedReader(isr);

                 String s = null ;

                 while ((s = br.readLine()) != null ) {

                         byte [] buf = s.getBytes( "UTF-8" );

                         for ( int j=0; j<buf. length ; j++){

                                 System. out .println(buf[j]);

                         }

                 }

         } catch (Exception e){

                 e.printStackTrace();

         } finally {

                 try {

                         fis.close();

                         isr.close();

                 } catch (Exception e){

                         e.printStackTrace();

                 }

         }

}

 

3 1 2 的读取结果 byte[] 进行比较,如果相同,那么可以认为文件的保存格式为 UTF-8 (虽然存在全英文 ansi 保存的可能,但是这种状况认为是 utf-8 保存不会有影响) , 如果不同则不是 UTF-8, 考虑我们目前状况,那么不是 UTF-8 可以认为文件保存编码就是 ANSI ,如果不可以这么认为,其他编码类型也要做这个判断。因为英文字符在任何编码下面读取出来的 byte[] 都是一样的。所以这里有一个效率问题,必须文件内容全部比较,不能只比较一部分。

 

以上推测经测试有效,没有问题。

如果使用第三方开源代码 common-io.jar 的话,可以将以上思路简化为如下代码。

public boolean isUTF8(File file){

       

try {

        byte [] buf = FileUtils.readFileToByteArray (file);

        String filecCntent = FileUtils.readFileToString (file, "UTF-8" );

        if (filecCntent.equals( new String(buf, "UTF-8" ))){

                return true ;

        }

} catch (IOException e) {

        // TODO 動生成された catch ブロック

        e.printStackTrace();

}

return false

}

 

 

这个判定有一个效率问题,在这个文章中采用的是读取整个文件,如 果我们文件太大,会比较花时间。这种情况可以考虑按行来读取判定,某一行不一致就可以退出了。这样可以提高一些效率。

分享到:
评论

相关推荐

    php汉字转拼音 降汉字转换为拼音,utf-8

    3. **Unicode与UTF-8**: UTF-8是一种基于Unicode的编码方式,对于汉字转拼音来说,确保输入的字符串是UTF-8编码是非常重要的,因为非UTF-8编码可能会导致乱码。 4. **拼音处理**: 在转换过程中,需要考虑多音字(一...

    gssdgv-zhuan-ke-master_java_

    《蚂蚁集团开源的Java研发框架——gssdgv-zhuan-ke-master_java_详解》 在现代软件开发中,高效、稳定且易维护的框架是项目成功的关键因素之一。蚂蚁集团作为全球知名的金融科技公司,其开源的Java研发框架——...

    snake-master-cuda8-zhuan_pt.tar

    Deep Snake for Real-Time Instance Segmentation pytorch1.0 cuda8转6个pt

    XUAN-ZHUAN-led.zip_旋转LED_旋转LED 自适应_自适应旋转LED

    "XUAN-ZHUAN-led.zip_旋转LED_旋转LED 自适应_自适应旋转LED"这个压缩包文件内容是关于实现旋转LED自适应转速的程序,其核心目标是让LED屏幕上的字幕能够流畅地滚动,并根据设备的转速自动调整滚动速度,以保持最佳...

    电子技术基础教学完美版-1

    电子技术基础教学完美版电子技术基础教学完美版电子技术基础教学完美版电子技术基础教学完美版电子技术基础教学完美版

    csv导入sqlite工具

    - 乱码问题:确保CSV文件是UTF-8编码,如果不确定,可以使用工具如Notepad++转换编码。 - 字段对齐:CSV的列数要与SQLite表的字段数匹配,否则会导致导入失败。 - 数据类型不匹配:SQLite的字段类型与CSV的数据...

    ban-zhuan.zip_JAVA穷举法搬砖_搬砖_用JAVA穷举法

    在给定的“ban-zhuan.zip_JAVA穷举法搬砖”主题中,我们面对的是一个数学问题,该问题与实际的砖块分配有关。36块砖需要36个人来搬运,其中包括男性、女性和小孩,他们各自有不同的搬运能力。男性每次能搬4块砖,...

    ruby中文转拼音的api

    在模型中引入文件。 require "pinyin" 按后实例化一个pinyin py = PinYin.instance py.to_pinyin_abbr("刘德华") #=&gt; ldh py.to_permlink('中文轉漢語拼音') #=&gt; "zhong-wen-zhuan-han-yu-pin-yin" py.to_...

    z zhuan sec_EH4_EH4Z文件转SEC文件_

    在IT行业中,转换不同格式的文件是一项常见的任务,特别是在嵌入式系统开发或者软件工程领域。标题中的"z zhuan sec_EH4_EH4Z文件转SEC文件_"表明我们正在处理一个涉及到将EH4或EH4Z格式的文件转换为SEC格式的议题。...

    zhuan-su-eliang.rar_labview 测_labview 测速_labview测速_labview转速测量_转

    在给定的“zhuan-su-eliang.rar”压缩包中,包含了一个名为“zhuan su eliang.vi”的虚拟仪器(VI),这显然是一款用于转速测量的应用程序。 转速测量是机械工程、汽车工业、电力系统等领域中常见的技术需求。...

    C++课程设计-超市管理系统源码.doc

    - `zhuan()`方法将临时文件的内容覆盖到原有文件,并清空临时文件。 3. **文件操作**: - 使用`&lt;fstream&gt;`库进行文件操作,如`ifstream`用于读文件,`ofstream`用于写文件。 - `ios::app`标志用于追加模式写入...

    ruby-pingyin ruby中将中文转化成拼音

    在模型中引入文件。 require "pinyin" 按后实例化一个pinyin py = PinYin.instance py.to_pinyin_abbr(" 刘德华") #=&gt; ldh py.to_permlink('中文轉漢語拼音') #=&gt; "zhong-wen-zhuan-han-yu-pin-yin" py.to_...

    zhuan-kai-fa

    标题“zhuan-kai-fa”似乎是在简写或拼音化表示“专开发”,这可能是指专门的软件开发或者技术开源项目。由于没有具体的标签信息,我们将从一般软件开发的角度来探讨相关知识点。 在软件开发领域,"专开发"可以涵盖...

    编码器计数

    编码器计数 fen=TH0*256+TL0-65335; bai_fen=fen/100; shi_fen=fen0/10; ge_fen=fen/10; bai_zhuan=(int)zhuan/100; shi_zhuan=(int)zhuan0/10; ge_zhuan=(int)zhuan; write_data(table[bai_fen]); ...

    C#代码重构 - Mr.Fu _Zhuan.mobi

    重构是迅速发现并修复有问题的代码的一种高效的方式。在《代码重构(c # & asp.net版)》中首次提供了在c#和asp.net中进行重构的专业方法,您将学习如何运用重构技术管理和修改代码

    2.6.14 内核移植说明文档(zhuan)

    ### 2.6.14 内核移植与YAFFS文件系统支持详解 #### 一、2.6.14 内核移植步骤 **1. 清除中间文件** - **背景**: 如果您使用的是其他人移植好的内核版本,则在开始编译之前应该清除中间文件。这是为了避免因使用的...

    ffmpeg h264 转换jpg

    FFmpeg是一款强大的开源多媒体处理工具,它支持各种视频、音频格式的编码、解码、转换、流媒体处理等操作。在本场景中,我们将重点讨论如何利用FFmpeg 3.4.1版本,针对64位系统,并使用VS2012编译环境,将H264编码的...

    python pandas实现excel转为html格式的方法

    最后,我们使用`codecs.open`打开一个文件,以写入模式('w')创建或覆盖HTML文件,并指定编码为UTF-8。 ```python with codecs.open('/path/to/your/output.html', 'w', 'utf-8') as html_file: html_file.write...

    php汉字转拼音

    function Pinyin($_String, $_Code='gb2312') { $_DataKey = "a|ai|an|ang|ao|ba|bai|ban|bang|bao|bei|ben|beng|bi|bian|biao|bie|bin|bing|bo|...//第二个参数随意设置则为utf-8编码 //echo Pinyin('张恩民',1); ?&gt;

    xlsx课表转ics日历格式文件

    "xlsx课表转ics日历格式文件"的课题就是解决这个问题的一种方法。它涉及到如何将Excel(xlsx)格式的课表转换为ics(iCalendar)格式,使得这些课表能够方便地导入到各种日历应用中,如Google日历、Apple日历或...

Global site tag (gtag.js) - Google Analytics