首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件架构设计 >

New IO 读写文件,编码出现有关问题

2012-11-05 
New IO 读写文件,编码出现问题!最近在做一个FileUtil,技术采用New IO, 在做的时候出现了编码问题!例如:我

New IO 读写文件,编码出现问题!
最近在做一个FileUtil,技术采用New IO, 在做的时候出现了编码问题!
例如:
我采用writeFile("D:\test.txt","中国",null)
然后我用readFile("D:\test.txt")读结果就会返回乱码!
后来我用Charset解码 , 获取目标文件编码(System.getProperty("file.encoding")),但是还是不行.
估计我应该要获得目标文件字节流的编码,这样才能根据相应的编码去读文件.
我怎么样才能判断目标文件的字节流编码呢?
或许我们会有更好的办法.请各位指教?谢谢!

    1 楼    wennew    2008-06-06              你底下writeFile用的utf-8,上面private static Charset charset = Charset.forName("UTF-8");就可以了。    2 楼    wennew    2008-06-06              要不然都用系统默认的编码,在writeFile时, out.write(ByteBuffer.wrap(content.getBytes()));  不使用encoding就是系统默认的编码。     3 楼    zjit    2008-06-06              这个是不会出现乱码。但是需求是:writeFile可以自定义编码写文件。所以不能采用默认的。有什么方法可以判断目标文件的编码吗?是文件字节流的编码?这样我就可以以相同的编码读文件!    4 楼    myy    2008-06-06              zjit 写道有什么方法可以判断目标文件的编码吗?是文件字节流的编码?这样我就可以以相同的编码读文件!

严格来说,没有绝对有效的办法判断(如果没有任何其他标识的话),当然,有的软件比较智能,能通过分析文件部分内容“猜出”编码,比如 UltraEdit等。

你可以看看 xml, html, http header... 中都需要有专门的 encoding, charset 之类的东西. 5 楼 tianzhihua 2008-06-09   <pre name='code' class='java'>package org.simpleframework.util;
import junit.framework.TestCase;
public class StringEncodingTest extends TestCase{
?public void testGetEncoding() throws Exception{
??System.out.println(new StringEncoding().getEncoding("费多少发送到费多少".getBytes()).getEncoding());
??
??System.out.println(new StringEncoding().getEncoding("費多少 費多少".getBytes()).getEncoding());
??
??System.out.println(new StringEncoding().getEncoding("あなたの訳すセンテンスを入力して下さい".getBytes()).getEncoding());
?}
}
</pre>
<pre name='code' class='java'/>
<pre name='code' class='java'>package org.simpleframework.util;

public class StringEncoding{
public static final class Encoding{
private String name;
private String encoding;

public Encoding(String name,String encoding){
this.name = name;
this.encoding = encoding;
}

public String getName() {
return name;
}

public String getEncoding() {
return encoding;
}
}

private final static int GB2312 = 0;

private final static int GBK = 1;
   
    private final static int BIG5 = 2;

    private final static int UTF8 = 3;

    private final static int UNICODE = 4;

    private final static int EUC_KR = 5;

    private final static int SJIS = 6;

    private final static int EUC_JP = 7;

    private final static int ASCII = 8;

    private final static int UNKNOWN = 9;


    private final static int TOTALT = 10;


    private static Encoding[] encodings;

    private int[][] GB2312format;
private int[][] GBKformat;
private int[][] Big5format;
private int[][] EUC_KRformat;
private int[][] JPformat;


    static{
    initEncodings();
    }

private static void initEncodings() {

encodings = new Encoding[TOTALT];
       
        int i = 0;
        encodings[i++] = new Encoding("GB2312","GB2312");
        encodings[i++] = new Encoding("GBK","GBK");
        encodings[i++] = new Encoding("BIG5","BIG5");
        encodings[i++] = new Encoding("UTF8","UTF-8");
        encodings[i++] = new Encoding("UNICODE(UTF-16)","UTF-16");
        encodings[i++] = new Encoding("EUC-KR","EUC-KR");
        encodings[i++] = new Encoding("Shift-JIS","Shift_JIS");
        encodings[i++] = new Encoding("EUC-JP","EUC-JP");
        encodings[i++] = new Encoding("ASCII","ASCII");
        encodings[i++] = new Encoding("ISO8859-1","ISO8859-1");
       
      
}

public StringEncoding(){
init();
}

private void init() {
GB2312format = new int[94][94];
        GBKformat = new int[126][191];
        Big5format = new int[94][158];
        EUC_KRformat = new int[94][94];
        JPformat = new int[94][94];
}

    public Encoding getEncoding(final byte[] data){
        return check(getEncodingValue(data));
    }

    private static Encoding check(final int result){
        if (result == -1){
            return encodings[UNKNOWN];
        }
        return encodings[result];

    }

    private int getEncodingValue(byte[] content){
        if (content == null)
            return -1;
        int[] scores;
        int index, maxscore = 0;
        int encoding = UNKNOWN;
        scores = new int[TOTALT];
        // 分配或然率
        scores[GB2312] = getProbabilityByGB2312Encoding(content);
        scores[GBK] = getProbabilityByGBKEncoding(content);
        scores[BIG5] = getProbabilityByBIG5Encoding(content);
        scores[UTF8] = getProbabilityByUTF8Encoding(content);
        scores[UNICODE] = getProbabilityByUTF16Encoding(content);
        scores[EUC_KR] = getProbabilityByEUC_KREncoding(content);
        scores[ASCII] = getProbabilityByASCIIEncoding(content);
        scores[SJIS] = getProbabilityBySJISEncoding(content);
        scores[EUC_JP] = getProbabilityByEUC_JPEncoding(content);
        scores[UNKNOWN] = 0;

        // 概率比较
        for (index = 0; index &lt; TOTALT; index++){
            if (scores[index] &gt; maxscore){
                // 索引
                encoding = index;
                // 最大几率
                maxscore = scores[index];
            }
        }
        // 返回或然率大于50%的数据
        if (maxscore &lt;= 50){
            encoding = UNKNOWN;
        }
        return encoding;
    }

    /** *//**
     * gb2312数据或然率计算
     *
     * @param content
     * @return
     */
    private int getProbabilityByGB2312Encoding(byte[] content){
        int i, rawtextlen = 0;

        int dbchars = 1, gbchars = 1;
        long gbformat = 0, totalformat = 1;
        float rangeval = 0, formatval = 0;
        int row, column;

        // 检查是否在亚洲汉字范围内
        rawtextlen = content.length;
        for (i = 0; i &lt; rawtextlen - 1; i++){
            if (content[i] &gt;= 0){
            } else{
                dbchars++;
                // 汉字GB码由两个字节组成,每个字节的范围是0xA1 ~ 0xFE
                if ((byte) 0xA1 &lt;= content[i] &amp;&amp; content[i] &lt;= (byte) 0xF7
                        &amp;&amp; (byte) 0xA1 &lt;= content[i + 1]
                        &amp;&amp; content[i + 1] &lt;= (byte) 0xFE){
                    gbchars++;
                    totalformat += 500;
                    row = content[i] + 256 - 0xA1;
                    column = content[i + 1] + 256 - 0xA1;
                    if (GB2312format[row][column] != 0){
                        gbformat += GB2312format[row][column];
                    } else if (15 &lt;= row &amp;&amp; row &lt; 55){
                        // 在gb编码范围
                        gbformat += 200;
                    }

                }
                i++;
            }
        }
        rangeval = 50 * ((float) gbchars / (float) dbchars);
        formatval = 50 * ((float) gbformat / (float) totalformat);

        return (int) (rangeval + formatval);
    }

    /** *//**
     * gb2312或然率计算
     *
     * @param content
     * @return
     */
    private int getProbabilityByGBKEncoding(byte[] content){
        int i, rawtextlen = 0;

        int dbchars = 1, gbchars = 1;
        long gbformat = 0, totalformat = 1;
        float rangeval = 0, formatval = 0;
        int row, column;
        rawtextlen = content.length;
        for (i = 0; i &lt; rawtextlen - 1; i++){
            if (content[i] &gt;= 0){
            } else{
                dbchars++;
                if ((byte) 0xA1 &lt;= content[i] &amp;&amp; content[i] &lt;= (byte) 0xF7
                        &amp;&amp; // gb范围
                        (byte) 0xA1 &lt;= content[i + 1]
                        &amp;&amp; content[i + 1] &lt;= (byte) 0xFE){
                    gbchars++;
                    totalformat += 500;
                    row = content[i] + 256 - 0xA1;
                    column = content[i + 1] + 256 - 0xA1;
                    if (GB2312format[row][column] != 0){
                        gbformat += GB2312format[row][column];
                    } else if (15 &lt;= row &amp;&amp; row &lt; 55){
                        gbformat += 200;
                    }

                } else if ((byte) 0x81 &lt;= content[i]
                        &amp;&amp; content[i] &lt;= (byte) 0xFE &amp;&amp; // gb扩展区域
                        (((byte) 0x80 &lt;= content[i + 1] &amp;&amp; content[i + 1] &lt;= (byte) 0xFE) || ((byte) 0x40 &lt;= content[i + 1] &amp;&amp; content[i + 1] &lt;= (byte) 0x7E))){
                    gbchars++;
                    totalformat += 500;
                    row = content[i] + 256 - 0x81;
                    if (0x40 &lt;= content[i + 1] &amp;&amp; content[i + 1] &lt;= 0x7E){
                        column = content[i + 1] - 0x40;
                    } else{
                        column = content[i + 1] + 256 - 0x40;
                    }
                    if (GBKformat[row][column] != 0){
                        gbformat += GBKformat[row][column];
                    }
                }
                i++;
            }
        }
        rangeval = 50 * ((float) gbchars / (float) dbchars);
        formatval = 50 * ((float) gbformat / (float) totalformat);
        return (int) (rangeval + formatval) - 1;
    }

    /** *//**
     * 解析为big5的或然率
     *
     * @param content
     * @return
     */
    private int getProbabilityByBIG5Encoding(byte[] content){
        int i, rawtextlen = 0;
        int dbchars = 1, bfchars = 1;
        float rangeval = 0, formatval = 0;
        long bfformat = 0, totalformat = 1;
        int row, column;
        rawtextlen = content.length;
        for (i = 0; i &lt; rawtextlen - 1; i++){
            if (content[i] &gt;= 0){
            } else{
                dbchars++;
                if ((byte) 0xA1 &lt;= content[i]
                        &amp;&amp; content[i] &lt;= (byte) 0xF9
                        &amp;&amp; (((byte) 0x40 &lt;= content[i + 1] &amp;&amp; content[i + 1] &lt;= (byte) 0x7E) || ((byte) 0xA1 &lt;= content[i + 1] &amp;&amp; content[i + 1] &lt;= (byte) 0xFE))){
                    bfchars++;
                    totalformat += 500;
                    row = content[i] + 256 - 0xA1;
                    if (0x40 &lt;= content[i + 1] &amp;&amp; content[i + 1] &lt;= 0x7E){
                        column = content[i + 1] - 0x40;
                    } else{
                        column = content[i + 1] + 256 - 0x61;
                    }
                    if (Big5format[row][column] != 0){
                        bfformat += Big5format[row][column];
                    } else if (3 &lt;= row &amp;&amp; row &lt;= 37){
                        bfformat += 200;
                    }
                }
                i++;
            }
        }
        rangeval = 50 * ((float) bfchars / (float) dbchars);
        formatval = 50 * ((float) bfformat / (float) totalformat);

        return (int) (rangeval + formatval);
    }

    /** *//**
     * 在utf-8中的或然率
     *
     * @param content
     * @return
     */
    private int getProbabilityByUTF8Encoding(byte[] content){
        int score = 0;
        int i, rawtextlen = 0;
        int goodbytes = 0, asciibytes = 0;
        // 检查是否为汉字可接受范围
        rawtextlen = content.length;
        for (i = 0; i &lt; rawtextlen; i++){
            if ((content[i] &amp; (byte) 0x7F) == content[i]){
                asciibytes++;
            } else if (-64 &lt;= content[i] &amp;&amp; content[i] &lt;= -33
                    &amp;&amp; i + 1 &lt; rawtextlen &amp;&amp; -128 &lt;= content[i + 1]
                    &amp;&amp; content[i + 1] &lt;= -65){
                goodbytes += 2;
                i++;
            } else if (-32 &lt;= content[i] &amp;&amp; content[i] &lt;= -17
                    &amp;&amp; i + 2 &lt; rawtextlen &amp;&amp; -128 &lt;= content[i + 1]
                    &amp;&amp; content[i + 1] &lt;= -65 &amp;&amp; -128 &lt;= content[i + 2]
                    &amp;&amp; content[i + 2] &lt;= -65){
                goodbytes += 3;
                i += 2;
            }
        }

        if (asciibytes == rawtextlen){
            return 0;
        }

        score = (int) (100 * ((float) goodbytes / (float) (rawtextlen - asciibytes)));
        // 如果不高于98则减少到零
        if (score &gt; 98){
            return score;
        } else if (score &gt; 95 &amp;&amp; goodbytes &gt; 30){
            return score;
        } else{
            return 0;
        }

    }

    /** *//**
     * 检查为utf-16的或然率
     *
     * @param content
     * @return
     */
    private int getProbabilityByUTF16Encoding(byte[] content){

        if (content.length &gt; 1
                &amp;&amp; ((byte) 0xFE == content[0] &amp;&amp; (byte) 0xFF == content[1])
                || ((byte) 0xFF == content[0] &amp;&amp; (byte) 0xFE == content[1])){
            return 100;
        }
        return 0;
    }

    /** *//**
     * 检查为ascii的或然率
     *
     * @param content
     * @return
     */
    private static int getProbabilityByASCIIEncoding(byte[] content){
        int score = 75;
        int i, rawtextlen;

        rawtextlen = content.length;

        for (i = 0; i &lt; rawtextlen; i++){
            if (content[i] &lt; 0){
                score = score - 5;
            } else if (content[i] == (byte) 0x1B){ // ESC (used by ISO 2022)
                score = score - 5;
            }
            if (score &lt;= 0){
                return 0;
            }
        }
        return score;
    }

    /** *//**
     * 检查为euc_kr的或然率
     *
     * @param content
     * @return
     */
    private int getProbabilityByEUC_KREncoding(byte[] content){
        int i, rawtextlen = 0;

        int dbchars = 1, krchars = 1;
        long krformat = 0, totalformat = 1;
        float rangeval = 0, formatval = 0;
        int row, column;
        rawtextlen = content.length;
        for (i = 0; i &lt; rawtextlen - 1; i++){
            if (content[i] &gt;= 0){
            } else{
                dbchars++;
                if ((byte) 0xA1 &lt;= content[i] &amp;&amp; content[i] &lt;= (byte) 0xFE
                        &amp;&amp; (byte) 0xA1 &lt;= content[i + 1]
                        &amp;&amp; content[i + 1] &lt;= (byte) 0xFE){
                    krchars++;
                    totalformat += 500;
                    row = content[i] + 256 - 0xA1;
                    column = content[i + 1] + 256 - 0xA1;
                    if (EUC_KRformat[row][column] != 0){
                        krformat += EUC_KRformat[row][column];
                    } else if (15 &lt;= row &amp;&amp; row &lt; 55){
                        krformat += 0;
                    }

                }
                i++;
            }
        }
        rangeval = 50 * ((float) krchars / (float) dbchars);
        formatval = 50 * ((float) krformat / (float) totalformat);

        return (int) (rangeval + formatval);
    }

    private int getProbabilityByEUC_JPEncoding(byte[] content){
        int i, rawtextlen = 0;

        int dbchars = 1, jpchars = 1;
        long jpformat = 0, totalformat = 1;
        float rangeval = 0, formatval = 0;
        int row, column;

        rawtextlen = content.length;
        for (i = 0; i &lt; rawtextlen - 1; i++){
            if (content[i] &gt;= 0){
            } else{
                dbchars++;
                if ((byte) 0xA1 &lt;= content[i] &amp;&amp; content[i] &lt;= (byte) 0xFE
                        &amp;&amp; (byte) 0xA1 &lt;= content[i + 1]
                        &amp;&amp; content[i + 1] &lt;= (byte) 0xFE){
                    jpchars++;
                    totalformat += 500;
                    row = content[i] + 256 - 0xA1;
                    column = content[i + 1] + 256 - 0xA1;
                    if (JPformat[row][column] != 0){
                        jpformat += JPformat[row][column];
                    } else if (15 &lt;= row &amp;&amp; row &lt; 55){
                        jpformat += 0;
                    }

                }
                i++;
            }
        }
        rangeval = 50 * ((float) jpchars / (float) dbchars);
        formatval = 50 * ((float) jpformat / (float) totalformat);

        return (int) (rangeval + formatval);
    }

    private int getProbabilityBySJISEncoding(byte[] content){
        int i, rawtextlen = 0;

        int dbchars = 1, jpchars = 1;
        long jpformat = 0, totalformat = 1;
        float rangeval = 0, formatval = 0;
        int row, column, adjust;

        rawtextlen = content.length;
        for (i = 0; i &lt; rawtextlen - 1; i++){
            if (content[i] &gt;= 0){
            } else{
                dbchars++;
                if (i + 1 &lt; content.length
                        &amp;&amp; (((byte) 0x81 &lt;= content[i] &amp;&amp; content[i] &lt;= (byte) 0x9F) || ((byte) 0xE0 &lt;= content[i] &amp;&amp; content[i] &lt;= (byte) 0xEF))
                        &amp;&amp; (((byte) 0x40 &lt;= content[i + 1] &amp;&amp; content[i + 1] &lt;= (byte) 0x7E) || ((byte) 0x80 &lt;= content[i + 1] &amp;&amp; content[i + 1] &lt;= (byte) 0xFC))){
                    jpchars++;
                    totalformat += 500;
                    row = content[i] + 256;
                    column = content[i + 1] + 256;
                    if (column &lt; 0x9f){
                        adjust = 1;
                        if (column &gt; 0x7f){
                            column -= 0x20;
                        } else{
                            column -= 0x19;
                        }
                    } else{
                        adjust = 0;
                        column -= 0x7e;
                    }
                    if (row &lt; 0xa0){
                        row = ((row - 0x70) &lt;&lt; 1) - adjust;
                    } else{
                        row = ((row - 0xb0) &lt;&lt; 1) - adjust;
                    }

                    row -= 0x20;
                    column = 0x20;
                    if (row &lt; JPformat.length &amp;&amp; column &lt; JPformat[row].length
                            &amp;&amp; JPformat[row][column] != 0){
                        jpformat += JPformat[row][column];
                    }
                    i++;
                } else if ((byte) 0xA1 &lt;= content[i]
                        &amp;&amp; content[i] &lt;= (byte) 0xDF){
                }

            }
        }
        rangeval = 50 * ((float) jpchars / (float) dbchars);
        formatval = 50 * ((float) jpformat / (float) totalformat);

        return (int) (rangeval + formatval) - 1;
    }

   
   

}

</pre>
<p>?</p> 6 楼 tianzhihua 2008-06-09   声明一下,上面的代码来源是从网上看到的,自己修改了一下,出自那里忘记了 7 楼 zjit 2008-06-09   多谢tianzhihua.

热点排行