2013-06-28 8 views
6

G-Clef(U + 1D11E)はBasic Multilingual Plane(BMP)の一部ではないため、16ビット以上必要です。ほとんどのJavaの読み取り関数は、charまたはintにはonly 16 bitも含まれています。 SMP、SIP、TIP、SSP、PUAを含む完全なUnicodeシンボルを読み取る関数はどれですか?ファイルからUnicode G音部記号(U + 1D11E)を読み取る方法は?

更新

私は、入力ストリームから単一のUnicode記号(またはコードポイント)を読み取る方法を求めています。私はどちらの整数配列も持っていませんし、私は行を読みたいと思いません。

Character.toCodePoint()でコードポイントを作成することはできますが、この機能にはcharが必要です。反対側でcharを読み取ることはできません。read()intを返すためです。これまでのところ私の最高の解決策はこれですが、それでも安全でないキャストが含まれています:

public int read_code_point (Reader input) throws java.io.IOException 
{ 
    int ch16 = input.read(); 
    if (Character.isHighSurrogate((char)ch16)) 
    return Character.toCodePoint((char)ch16, (char)input.read()); 
    else 
    return (int)ch16; 
} 

どのように改善するのですか?

アップデート2

文字列を返すが、それでもキャストを使用して別のバージョン:

public String readchar (Reader input) throws java.io.IOException 
{ 
    int i16 = input.read(); // UTF-16 as int 
    if (i16 == -1) return null; 
    char c16 = (char)i16; // UTF-16 
    if (Character.isHighSurrogate(c16)) { 
    int low_i16 = input.read(); // low surrogate UTF-16 as int 
    if (low_i16 == -1) 
     throw new java.io.IOException ("Can not read low surrogate"); 
    char low_c16 = (char)low_i16; 
    int codepoint = Character.toCodePoint(c16, low_c16); 
    return new String (Character.toChars(codepoint)); 
    } 
    else 
    return Character.toString(c16); 
} 

残りの質問:キャストが安全であるか、どのようにそれらを避けるために?

+0

を使用することができますでき保証はタイトルに主要なタグを追加する必要はありません。 –

+3

[Unicode文字を含む文字ストリームでのJava読み込み]の複製が可能です(http://stackoverflow.com/questions/7721293/java-reading-in-character-streams-with-supplementary-unicode-characters) –

+1

可能な複製答えを含んでいません。 – ceving

答えて

0

これまでのところ私の最高の解決策はこれですが、まだ安全でないキャストが含まれています

あなたが提示したコードの安全でない唯一の点は、inputがEOFに達した場合、ch16が-1になる可能性があることです。この条件を最初にチェックすると、他のキャストがReader.read()is specifiedとして安全であることが保証され、-1または0-(0 - 0xFFFF)の範囲の値が返されます。

public int read_code_point (Reader input) throws java.io.IOException 
{ 
    int ch16 = input.read(); 
    if (ch16 < 0 || !Character.isHighSurrogate((char)ch16)) 
    return ch16; 
    else { 
    int loSurr = input.read(); 
    if(loSurr < 0 || !Character.isLowSurrogate((char)loSurr)) 
     return ch16; // or possibly throw an exception 
    else 
     return Character.toCodePoint((char)ch16, (char)loSurr); 
    } 
} 

これはまだあなたはおそらくしたい場合には、あなたが最初char読み取りが上位サロゲートであるエッジケースを処理する必要がありますが、二番目が一致下位サロゲートではありません実際に、理想的ではありません最初にcharに戻し、リーダーをバックアップして、次の読み取りで次の文字が表示されるようにします。しかし、それはinput.markSupported() == trueの場合にのみ動作します。あなたなら、どの程度

public int read_code_point (Reader input) throws java.io.IOException 
{ 
    int firstChar = input.read(); 
    if (firstChar < 0 || !Character.isHighSurrogate((char)firstChar)) { 
    return firstChar; 
    } else { 
    input.mark(1); 
    int secondChar = input.read(); 
    if(secondChar < 0) { 
     // reached EOF 
     return firstChar; 
    } else if(!Character.isLowSurrogate((char)secondChar)) { 
     // unpaired surrogates, un-read the second char 
     input.reset(); 
     return firstChar; 
    } 
    else { 
     return Character.toCodePoint((char)firstChar, (char)secondChar); 
    } 
    } 
} 

それとも、PushbackReaderで、元リーダーをラップし、unread(secondChar)

+0

これをコードポイントゲインに変換するのは何ですか?便利なことをしたいのであれば、データをStringに入れたいと思う可能性が最も高いです。 – jtahlborn

+0

@jtahlbornすべてのパーサーは、次の文字列ではなく次の文字を必要とします。パーサーは役に立たないとお考えですか? – ceving

-1

完全なUnicodeは、UTF-8とUTF-16の両方で、バイトのシーケンスによって表現することができます。バイトのペア( "java chars")。文字列から完全なUnicode コードポイントを用いて抽出することができます。基本的にはラテン文字を含むファイルについて

int[] codePoints = { 0x1d11e }; 
String s = new String(codePoints, 0, codePoints.length); 

for (int i = 0; i < s.length();) { 
    int cp = s.codePointAt(i); 
    i += Character.charCount(cp); 
} 

、UTF-8は、罰金と思われます。

String s = unicodeToString(0x1d11e); 
String s = unicodeToString(0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x1d11e); 

public static String unicodeToString(int... codepoints) { 
    return new String(codePoints, 0, codePoints.length); 
} 

try (BufferedReader in = new BufferedReader(
     new InputStreamReader(new FileInputStream(file), "UTF-8"))) { 
    for (;;) { 
     String line = in.readLine(); 
     if (line == null) { 
      break; 
     } 
     ... do some thing with a Unicode line ... 
    } 
} catch (FileNotFoundException e) { 
    System.err.println("No file: " + file.getPath()); 
} catch (IOException e) { 
    ... 
} 

1つ(または複数のUnicodeコード)のJavaのStringを配信機能:以下カントー

は、(UTF-8)完全標準Unicodeファイルを読み込み

+0

答えは入力ストリームの関数を指していません。 – ceving

+0

詳しくはこちら。ここでは、ファイル、FileInputStreamから読み込みます。たぶん混乱は、Unicode自体が形式ではなく、記号の標準的な番号付けであることです。 UTF-8、UTF-16LE、UTF-16BE、UTF-16は実際のバイナリ形式です。実際には、Javaは2つの形式のUnicodeを使用します。ただし、 'char'は.classのUTF-16です。文字列定数はUTF-8として保存されます。 ** UTF-8は完全なUnicodeをカバーしています。**上記のコードでは、 'codePoints'配列はUnicode番号を使用しています。 –

+1

完全な行ではなく単一の記号を尋ねられました。 'readline'を使うと、残りの行を読むことが必要になります。 – ceving

関連する問題