質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

PDF

PDF(Portable Document Format)とはISOによって国際標準として制定されている電子ドキュメント用の拡張子です。

Q&A

解決済

2回答

7484閲覧

Javaを用いたFlatedecode(Zip形式)圧縮されたバイナリデータの解凍

tktk123

総合スコア11

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

PDF

PDF(Portable Document Format)とはISOによって国際標準として制定されている電子ドキュメント用の拡張子です。

0グッド

0クリップ

投稿2016/11/02 04:23

###前提・実現したいこと
PDFファイルからの文字データ読み出しを作成していたのですが、"stream"~"endstream"で囲まれたバイナリデータ部分がFlateDecodeというZIP形式で圧縮されていて読むことが出来ません。
そこでバイナリデータ部のみを切り出したテキストファイルからバイナリデータを読み込みjava.util.zip.Inflaterを用いて解凍するプログラムを作成しているのですが、一通り組み終わり実行したところエラーメッセージがでてうまく進めることが出来ない状態です。

###発生している問題・エラーメッセージ

Exception in thread "main" java.util.zip.DataFormatException: invalid code lengths set at java.util.zip.Inflater.inflateBytes(Native Method) at java.util.zip.Inflater.inflate(Inflater.java:259) at java.util.zip.Inflater.inflate(Inflater.java:280) at ProcessFlateDecode.ProcessFlateDecode.main(ProcessFlateDecode.java:37)

###該当のソースコード

java

1import java.io.FileInputStream; 2import java.util.ArrayList; 3import java.util.zip.Inflater; 4 5class ProcessFlateDecode { 6 7 public static void main(String[] args) throws Exception{ 8 9 ArrayList<Integer> list = new ArrayList<Integer>(); 10 11 FileInputStream ins = new FileInputStream("file.txt"); 12 13 while(true){ 14 int data = ins.read(); 15 if(data==-1) break; 16 17 list.add( data ); 18 } 19 ins.close(); 20 21 22 int compressedDataLength = list.size(); 23 byte[] output = new byte[compressedDataLength]; 24 for(int i=0; i<list.size(); i++){ 25 Integer o=(Integer)list.get(i); 26 output[i]=(byte)(o.intValue()); 27 } 28 29 Inflater decompresser = new Inflater(); 30 decompresser.setInput(output, 0, compressedDataLength); 31 byte[] result = new byte[100]; 32 int resultLength = decompresser.inflate(result); 33 34 decompresser.end(); 35 36 String outputString = new String(result, 0, resultLength, "UTF-8"); 37 System.out.println(outputString); 38 } 39 40}

###補足情報(言語/FW/ツール等のバージョンなど)
実行環境としてはeclipse4.6Neonを利用しています。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

圧縮されたデータをPDFから切り出してファイルへ出力するところで文字化けしているということはないでしょうか?その部分の処理が提示されてないので単なる推測です。

蛇足1:
バイナリーデータを読み込む処理に不自然に思える点があります。

  1. 入力ファイル名の拡張子が.txt

直接論理には関係ありませんがバイナリーデータを格納するファイルに.txtという拡張子は不自然と思います。
2. 入力ファイルの読み込み方
ファイルの中身はInflater#setInputでbyte配列として渡すことになります。よって入力ストリームからbyte配列へ直接readする方が自然です。ファイルに格納されている全バイト数が必要ならファイルのサイズを求めるメソッドで直接求められます。以上からList<Integer>への読み込みは冗長といえます。また他の理由で一旦全データを読み込む必要があるならList<Integer>ではなくByteBufferなどのクラスを使った方が自然に思えます。

蛇足2:
上げておられる圧縮解除論理は「とりあえず試しにコーディングしてみた」というレベルかも知れません。もしそうならいいのですが、最終実装だとするとInflater関連の実装が中途半端であると思います。UTF-8エンコードされた100バイト以上の文字列が存在すると破綻するからです。本来はinflate/setInputを適切に呼び出しながら全部のデータの解凍が完了するまでループするような制御が必要だと思います。

蛇足3:
Inflaterの代わりにInflaterInputStreamを使うと圧縮データの入力ストリームを圧縮解除した入力ストリームへ簡単に変換できます。そのほうが楽かも知れません。


質問者さんからのコメントにより追記(11/7 19:04):

バイナリーデータ部分をテキストエディタで読み込んでいたとのことでしたので、やはり文字化けが原因と思います。一般にバイナリーデータはいったん文字へ変換すると(※)と元のデータは復元できません。それはバイナリーデータと文字データとの間の変換が通常は不可逆なためです。

PDFをJavaで扱うためには入力にバイナリー入力ストリーム(InputStream)を使い、文字であることがわかっている部分のみをStringへ変換するといった配慮が必要になります。文字とバイナリーが混在したデータを扱う処理は少々難易度が高く「こうするとよい」といった簡単なアドバイスが自分にはできません。PDFの中身を解析する目的自体には専用のライブラリーを使う方がよいかも知れません。「java PDFReader free」などで検索するといくつかあるようです。

※:文字へ変換
Java上では文字列ストリームを使ったり、Stringに変換したりすることにあたります。またテキストエディタで開くといったことも同様です。

投稿2016/11/02 06:25

編集2016/11/07 10:04
KSwordOfHaste

総合スコア18392

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tktk123

2016/11/07 08:54

恥ずかしながらテキストエディタで開いたものを切り取っていたので文字化けしたものを入力ファイルとして使っていました。。。 そこでPDFのバイナリデータのみを抽出するプログラムを書いていたのですが文字化けした形でなく、その部を進数に直した形でバイト列に入れてバイナリファイルとして保存すればよいのでしょうか?初歩的な質問で申し訳ありません。 また回答していただいたのに遅れてしまい申し訳ありません。
KSwordOfHaste

2016/11/07 10:06

そういうことでしたか。ここに記述しずらいので本文の方へ追記しておきました。
tktk123

2016/12/13 01:28

わかりやすくご丁寧にありがとうございました。なんとか参考にさせてもらい完成することができました。
guest

0

PDFのFlateDecodeについては、yamagu.exblog.jp|
PDFの仕様書を読む 第15回 3.2.7 Stream Objects - Standard Filters
が非常に役立つと思います。

投稿2016/11/02 06:25

A-pZ

総合スコア12011

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問