2016-08-26 7 views
1

UTF-16データストリームをチャンクに分割する際に助けを求めることができますか?swift utf16データストリーム - チャンクに分割する問題

残念ながら、文字の境界を見つけることにはかなり苦しんでいます。

何か助けていただきありがとうございました。この問題について何度かお伺いしましたが、この問題を理解することが大好きです。

だけで正常に動作するJavaのバージョンは、(最初​​の2つのバイトを分割する場合でも、出力はその2として正しい文字列を与えるよう任意の自動修正がありますか?):

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)); 
    } 
} 

Java出力:

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

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

スウィフト(Xcodeの8ベータ6、スイフト3)遊び場コード:

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)) 
} 

スウィフト出力:

Data size: 30 
    --------------------- 2 
    Optional("") 
    Optional("ఁ堁态搁ก紁䜁ഁ夁愁攁༁䠁ᬁ") 
    --------------------- 4 
    Optional("Č") 
    Optional("堁态搁ก紁䜁ഁ夁愁攁༁䠁ᬁ") 
    --------------------- 6 
    Optional("ČŘ") 
    Optional("态搁ก紁䜁ഁ夁愁攁༁䠁ᬁ") 
    --------------------- 8 
    Optional("ČŘŠ") 
    Optional("搁ก紁䜁ഁ夁愁攁༁䠁ᬁ") 
    --------------------- 10 
    Optional("ČŘŠŤ") 
    Optional("ก紁䜁ഁ夁愁攁༁䠁ᬁ") 
    --------------------- 12 
    Optional("ČŘŠŤĎ") 
    Optional("紁䜁ഁ夁愁攁༁䠁ᬁ") 

私はString.Encoding.utf8に迅速エンコーディングを変更した場合、予想通り、出力されますが、UTF16およびUTF32のために、私は何が起こっているかを理解していません。

ありがとうございました。

答えて

0

短い答え:使用utf16LittleEndianまたはutf16BigEndianエンコーディング 期待される結果を取得します

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

長い答え:utf16エンコードがで先頭に付加リトルエンディアン UTF-16のデータに文字列を変換しますバイトオーダーマーカー:

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

データi

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

誤って変換されるバイト順マーカーのない部分、それはビッグエンディアンバイト順が現在想定している明らかに :2つの部分にSの分割は、第二部はもうない 先頭のバイトオーダーマーカーを持っています:

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

ありがとう!これは理にかなって、JavaのUTF-16のデフォルトの処理はおそらく少し異なります。 – ds77

関連する問題