2012-03-16 17 views
21

UTF-8ファイルからBOMを削除し、残りのXMLファイルのコピーを作成する方法についての提案が必要です。JavaのXMLファイルからBOMを削除する方法

+1

downvotesがあるため、重複するのではありませんが、彼らはこの質問が広すぎるしているので:

そしてここでは、同様に他のエンコーディングをカバーし、より完全な答えと質問へのリンクです本質的に - stackoverflowは、特定のローカライズされたプログラミングの問題を助けるためのものです。私たちはあなたがプログラムをデバッグするのを助けることができます、我々はあなたのために1つを記述しません。 –

+0

私はこれが答える前に-5になるのを待っています。 ) – TacticalCoder

+0

@hari:ファイルのエンコーディングは何ですか? UTF-8? – TacticalCoder

答えて

32

UTF-8ファイルのBOMによりツールが破損しているのは、非常に私の経験では共通しています。なぜそれほど多くの下降音がどこにあるのか分かりません(しかし、特別なSOのバッジに勝つために十分な投票を得る機会が与えられます)。それほど意味がありますしかしそれは仕様によって完全に有効です(落胆しますが)。今問題は、多くの人がBOMがUTF-8で有効であることを認識しておらず、これらのファイルを正しく処理しない壊れたツールやAPIを書いていることです。

これは、Javaからファイルを処理したい場合や、Javaを使用して他の(破損した)ツールに必要なファイルをプログラムで作成または修正する必要がある場合の2つの問題があります。

私は、ヘルプデスクが、Javaによって生成された完全に有効なUTF-8ファイルを混乱させるテキストエディタで問題を抱えているユーザーからのメッセージを引き続き受け取るコンサルティングの機会に、このケースを持っていました。そのため、私たちが扱っていたすべてのUTF-8ファイルからBOMを削除するようにして、この問題を回避する必要がありました。

ファイルからBOMを削除したい場合は、新しいファイルを作成し、最初の3バイトをスキップすることができます。例:

... $ file /tmp/src.txt 
/tmp/src.txt: UTF-8 Unicode (with BOM) English text 

... $ ls -l /tmp/src.txt 
-rw-rw-r-- 1 tact tact 1733 2012-03-16 14:29 /tmp/src.txt 

... $ hexdump -C /tmp/src.txt | head -n 1 
00000000 ef bb bf 50 6f 6b 65 ... 

ご覧のとおり、ファイルは "ef bb bf"で始まります。これは(完全に有効な)UTF-8 BOMです。

ここでファイルを受け取り、最初の3つのバイトをスキップすることによって、それのコピーを作成する方法です:それは「生」だと

public static void workAroundbrokenToolsAndAPIs(File sourceFile, File destFile) throws IOException { 
    if(!destFile.exists()) { 
     destFile.createNewFile(); 
    } 

    FileChannel source = null; 
    FileChannel destination = null; 

    try { 
     source = new FileInputStream(sourceFile).getChannel(); 
     source.position(3); 
     destination = new FileOutputStream(destFile).getChannel(); 
     destination.transferFrom(source, 0, source.size() - 3); 
    } 
    finally { 
     if(source != null) { 
      source.close(); 
     } 
     if(destination != null) { 
      destination.close(); 
     } 
    } 
} 

注:通常、最初のあなたが持っていることを確認したいと思いますが、これを呼び出す前にBOM、または「Bad Thinks May Happen」[TM]のいずれかを選択します。

あなたはその後、あなたのファイルを見ることができます。

... $ file /tmp/dst.txt 
/tmp/dst.txt: UTF-8 Unicode English text 

... $ ls -l /tmp/dst.txt 
-rw-rw-r-- 1 tact tact 1730 2012-03-16 14:41 /tmp/dst.txt 

... $ hexdump -C /tmp/dst.txt 
00000000 50 6f 6b 65 ... 

そして、あなたは、単に透過的に1つのあなたの壊れたJava APIのためのBOMを削除したい場合はBOMは、あなたがして、今...

を行っていますpushbackInputStreamここで説明を使用することができます。why org.apache.xerces.parsers.SAXParser does not skip BOM in utf8 encoded xml?

private static InputStream checkForUtf8BOMAndDiscardIfAny(InputStream inputStream) throws IOException { 
    PushbackInputStream pushbackInputStream = new PushbackInputStream(new BufferedInputStream(inputStream), 3); 
    byte[] bom = new byte[3]; 
    if (pushbackInputStream.read(bom) != -1) { 
     if (!(bom[0] == (byte) 0xEF && bom[1] == (byte) 0xBB && bom[2] == (byte) 0xBF)) { 
      pushbackInputStream.unread(bom); 
     } 
    } 
    return pushbackInputStream; } 

注これは動作しますが、definばならないことitely NOT作業チェーン内の他のツールをBOMを持つUTF-8ファイルで正しく動作させることができない、より深刻な問題を修正しました。

Byte order mark screws up file reading in Java

+0

投票数質問の*件名*の判断ではなく、質問の*品質*の判断です。投票ボタンのツールチップを見てください。 – skaffman

+1

@skaffman:OKですが、downvotingの代わりにOPがUTF-8ファイルを使用していたかどうかを尋ねました(この問題はあまりにも一般的です)、それを質問に追加してタグを編集しました。私は他に何が言えるのか分かりません:* "ファイルからBOMを削除する方法は?" *はかなり自明です。私は「UTF-8」を追加しました。もちろん、単純にダウンボトムするのは簡単でした。 ) – TacticalCoder

+0

@ TacticalCoderのおかげでたくさんの提案がありました。これが私が持っていたpblmを解決できると確信しています。 – hari

関連する問題