swift utf16数据流 - 分成块的问题

时间:2016-08-26 23:33:36

标签: swift stream utf-16

我可以请求帮助将UTF-16数据流拆分成块吗?

不幸的是找到字母边界很痛苦。

任何帮助表示赞赏,已经花了好几个晚上,很想了解这个问题。

Java版本工作正常(有没有任何自动更正,因为即使分割前两个字节输出提供正确的字符串作为part2?):

v

Java输出:

public static void main(String[] args) throws Exception {
    String encoding = "UTF-16";
    byte[] data = "ČŘŠŤĎŽŇčřšťďňě".getBytes(encoding);

    System.out.println("Data size: "+data.length);

    for(int index=2; index<= data.length / 2; index+=2)
    {
        byte[] part1 = java.util.Arrays.copyOfRange(data, 0, index);
        byte[] part2 = java.util.Arrays.copyOfRange(data, index, data.length);

        assert(part1.length + part2.length == data.length);

        System.out.println("--------------------- "+index);

        System.out.println(new String(part1, encoding));
        System.out.println(new String(part2, encoding));
    }
}

Swift(Xcode 8 beta 6,Swift 3)游乐场代码:

Data size: 30
--------------------- 2

ČŘŠŤĎŽŇčřšťďňě
--------------------- 4
Č
ŘŠŤĎŽŇčřšťďňě
--------------------- 6
ČŘ
ŠŤĎŽŇčřšťďňě
--------------------- 8
....

快速输出:

import Foundation

let encoding = String.Encoding.utf16
let data = "ČŘŠŤĎŽŇčřšťďňě".data(using: encoding)!

print("Data size: \(data.count)")

for index in stride(from: 2, to: data.count/2, by: 2)
{
    let part1 = data.subdata(in: 0..<index)
    let part2 = data.subdata(in: index..<data.count)

    assert(part1.count + part2.count == data.count)


    print("--------------------- \(index)")
    print(String(data: part1, encoding: encoding))
    print(String(data: part2, encoding: encoding))
}

如果我将swift编码更改为String.Encoding.utf8,则输出符合预期,但对于utf16和utf32,我不明白发生了什么。

感谢。

1 个答案:

答案 0 :(得分:0)

简答:使用utf16LittleEndianutf16BigEndian编码 获得预期的结果:

Data size: 28
--------------------- 2
Optional("Č")
Optional("ŘŠŤĎŽŇčřšťďňě")
--------------------- 4
Optional("ČŘ")
Optional("ŠŤĎŽŇčřšťďňě")
--------------------- 6
Optional("ČŘŠ")
Optional("ŤĎŽŇčřšťďňě")
...

更长的答案: utf16编码将字符串转换为little-endian UTF-16数据,以字节顺序标记为前缀:

let data = "abc".data(using: .utf16)!
print(data as NSData) // <fffe6100 62006300>

当数据分为两部分时,第二部分则没有 领先的字节顺序标记:

let part1 = data.subdata(in: 0..<4)
let part2 = data.subdata(in: 4..<8)
print(part1 as NSData, part2 as NSData) // <fffe6100> <62006300>

显然,没有字节顺序标记的部分被错误地转换 它是现在假设的 big-endian 字节顺序:

print(String(data: part1, encoding: .utf16)) // Optional("a")
print(String(data: part2, encoding: .utf16)) // Optional("戀挀")
print(String(data: part2, encoding: .utf16LittleEndian)) // Optional("bc")