- ベストアンサー
ファイルIOと冒頭の謎の3バイトの対処方法
- Base64エンコード済みのEPS画像が埋め込まれたXMLをStAXで解析して、各画像を順次取り出しながらデコードして外部画像として保存する処理を書きました。
- 実行して画像を取り出して、各画像をAdobe Illustratorに読み込ませると、なぜか一番目の画像だけ読み込めません。
- 1番目の画像の冒頭の3バイトをバイナリエディタで取り除くと、Illustratorに読み込むことができます。どのようなことでもよいので、何かしらお気づきの方はどうかご指摘ください。
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
No.4です。訂正です。 > 1) 元のXMLファイルのEPSファイルに相当するBase64文字列に,既にその3バイト(6文字分)に対応するデータが付加されていますか? 誤:3バイト(6文字分) 正:3バイト(4文字分) これだけではなんですので,0x9ee965に相当するBase64文字列は'null'('n','u','l','l')でした。なので,XMLファイルに'null'という文字列が含まれていないか調べてみてください。
その他の回答 (4)
- aton
- ベストアンサー率47% (160/334)
1) 元のXMLファイルのEPSファイルに相当するBase64文字列に,既にその3バイト(6文字分)に対応するデータが付加されていますか? 2) 1がyesだった場合,XMLファイル読み取り・EPSファイル出力側で対応するより,EPSファイル入力・XMLファイル書き出し側で対応する方が正しいように思いますが,後者のソースコードにアクセスできますか? 3) どんなXMLファイルでも,この問題が起きるのは先頭のEPSファイルの3バイトだけですか? それとも任意のEPSファイルの任意のバイト数でこの問題が起きる可能性がありますか? 3が前者の場合,先頭のEPSファイルだけ最初の3バイトを飛ばして出力するようコードを変更すればいいように思います。後者の場合,「base64デコード済みバイト配列」の先頭から,EPSファイルの 'magic number' (0xC5D0D3C6; おそらく質問中にある8バイトの最初の4バイトはこれじゃないかと思います) 参考: http://en.wikipedia.org/wiki/List_of_file_signatures ("File extention"が"EPS"の行) を探し出し,見つけたところを始点としてEPSファイルを出力するようコードを変更すればいいと思います。
- 中村 拓男(@tknakamuri)
- ベストアンサー率35% (674/1896)
どうやって紛れ込んだかはこれだけの話ではわかりませんが、 その3バイトが EF BB BF なら UTF-8 の BOM でしょう。 外してたらすいません。
補足
ご回答ありがとうございます。 >> その3バイトが EF BB BF なら UTF-8 の BOM でしょう。 EF BB BF ではないような気がします(汗) No1, No2 の方に補足させていただきましたので、何か思い当たる節があれば追加でアドバイス等いただけるととても助かります。 よろしくお願いします。
- kmee
- ベストアンサー率55% (1857/3366)
その3バイト、バイナリエディタで見たときの値を覚えていませんか? おそらくUTF-8のBOMだと思います。 http://ja.wikipedia.org/wiki/UTF-8#.E3.83.90.E3.82.A4.E3.83.88.E9.A0.86.E3.83.9E.E3.83.BC.E3.82.AF.E3.81.AE.E4.BD.BF.E7.94.A8.E3.81.AB.E3.81.A4.E3.81.84.E3.81.A6 どの段階で付いたのかはわかりません。
補足
ご回答ありがとうございます。 >> その3バイト、バイナリエディタで見たときの値を覚えていませんか? Stirling で確認すると、00000000行目の冒頭から3バイトは、「9E E9 65」 でした。文字コードは Shift_JIS です。 また、参考URLより、 テキストデータがUTF-8で符号化されていることの標識として、データの先頭にEF BB BF (16進。UCSでのバイト順マークU+FEFFのUTF-8での表現) を付加することがある。 とありますが、「16進。UCSでのバイト順マークU+FEFFのUTF-8での表現」をjavaから出力させるためには、どのようにすればよいでしょうか? 環境は、OS は winxp, SE6, base64ライブラリ は apache の commons-codec-1.5 を使ってます。 XMLを読む箇所のコードは、以下の通りです。 BufferedInputStream stream = new BufferedInputStream(new FileInputStream("解析対象xmlのパス")); XMLInputFactory factory = XMLInputFactory.newInstance(); XMLStreamReader reader = factory.createXMLStreamReader(stream); 保存は以下の通りです。 fos = new FileOutputStream(file); bos = new BufferedOutputStream(fos); bos.write(base64デコード済みバイト配列); bos.close(); fos.close(); 勉強不足でストリーム/ファイルIOと文字コードの関係について十分に理解できていないのですが、何か気になることはありますでしょうか? 盛りだくさんで申し訳ありません、お手隙でしたらよろしくお願いします。
- bluehat43
- ベストアンサー率52% (9/17)
3バイトと聞いて思いつくのは、BOMとか? http://e-words.jp/w/BOM.html 恐らくですが、もともとのXML自体がBOM付きになっているのでは?
補足
ご回答ありがとうございます。 >> 恐らくですが、もともとのXML自体がBOM付きになっているのでは? 解析対象のXMLを notepad++ に読み込んでフォーマットを確認すると、BOMなしのUTF-8になっていました。バイナリエディタ Stirling に読み込ませると、1~3バイト目は 0A 3C 6C となっていました。 また、複数の画像を連続して保存しているのですが、最初の画像のみにBOMらしいものが付加されてしまうこともイマイチ理解できません。 それから…、1週間前(お盆休み前)に同じ処理を書いた時には、すべての画像にBOMらしいものが付加されずに書き出せたことがありました。その時の実行ファイル(jar)だけ残っています。(ソースが残っていません(汗)) ソースの書き方次第でゴミが付随するようなケースは考えられるのでしょうか…?
お礼
>> 1) 元のXMLファイルのEPSファイルに相当するBase64文字列に,既にその3バイト(6文字分)に対応するデータが付加されていますか? XMLファイルにはnullの文字列は見当たりませんでした。 >> これだけではなんですので,0x9ee965に相当するBase64文字列は'null'('n','u','l','l')でした。 なるほど…、ご丁寧にありがとうございます。 今度から暗号化文字列ではまった時には複合することにします…。なんだかすごいヒントをいただいた気がします…。 それから、No4の参考リンクはとてもに参考になりました。 ありがとうございます!