阅读UTF-16会产生意外结果

时间:2016-08-02 09:24:32

标签: java android encoding utf-16

我在Android项目中使用beaglebuddy Java库来读取/写入mp3文件的ID3标签。我在阅读以前使用相同库编写的文本时遇到问题,但在文档中找不到任何相关内容。

假设我写下以下信息:

MP3 mp3 = new MP3(pathToFile);
mp3.setLeadPerformer("Jon Skeet");
mp3.setTitle("A Million Rep");
mp3.save();

查看库的源代码,我看到UTF-16编码是显式设置的,在内部调用

protected ID3v23Frame setV23Text(String text, FrameType frameType) {
   return this.setV23Text(Encoding.UTF_16, text, frameType);
}

protected ID3v23Frame setV23Text(Encoding encoding, String text, FrameType frameType) {
    ID3v23FrameBodyTextInformation frameBody = null;
    ID3v23Frame frame = this.getV23Frame(frameType);
    if(frame == null) {
        frame = this.addV23Frame(frameType);
    }

    frameBody = (ID3v23FrameBodyTextInformation)frame.getBody();
    frameBody.setEncoding(encoding);
    frameBody.setText(encoding == Encoding.UTF_16?Utility.getUTF16String(text):text);
    return frame;
}

稍后,我读了数据,它给了我一些奇怪的汉字:

mp3.getLeadPerformer(); // 䄀 䴀椀氀氀椀漀渀 刀攀瀀
mp3.getTitle(); // 䨀漀渀 匀欀攀攀琀

我看了一下内置的Utility.getUTF16String(String)方法:

public static String getUTF16String(String string) {
    String text = string;
    byte[] bytes = string.getBytes(Encoding.UTF_16.getCharacterSet());
    if(bytes.length < 2 || bytes[0] != -2 || bytes[1] != -1) {
        byte[] bytez = new byte[bytes.length + 2];
        bytes[0] = -2;
        bytes[1] = -1;
        System.arraycopy(bytes, 0, bytez, 2, bytes.length);
        text = new String(bytez, Encoding.UTF_16.getCharacterSet());
    }

    return text;
}

我不太明白将前2个字节分别设置为-2和-1,这是一个模式,表明该字符串是UTF-16编码的吗?

但是,我尝试在读取数据时显式调用此方法,这似乎是可读的,但始终在一开始就预设了一些神秘的字符:

Utility.getUTF16String(mp3.getLeadPerformer()); // ��Jon Skeet
Utility.getUTF16String(mp3.getTitle()); // ��A Million Rep

由于这些字符的数量似乎是不变的,我只是通过简单地删除它们来创建一个临时的解决方法。

像“评论”这样的字段,其中作者在写入时没有明确强制执行UTF-16而没有任何问题。

我真的很好奇这里发生了什么,并感谢任何建议。

0 个答案:

没有答案