【问题标题】:java.lang.RuntimeException: java.util.zip.DataFormatException: incorrect header checkjava.lang.RuntimeException:java.util.zip.DataFormatException:不正确的标头检查
【发布时间】:2018-12-13 17:08:07
【问题描述】:

我的目标是从 pdf 文件中提取原始文本。我得到了字节数组,但内容是用 FlateDecode 算法编码的。所以我试图用这段代码解码原始内容

public String readTextFile(Uri uri){

    String mSelectedFilePath = FileUtils.getPath(MainActivity.this,
            uri);
    Log.e(TAG," path "+mSelectedFilePath);


    File sdcard = Environment.getExternalStorageDirectory();
    StringBuilder text = new StringBuilder();

    try {
        File file = new File(mSelectedFilePath);

        try {
            BufferedReader br = new BufferedReader(new FileReader(file));
            String line;

            while ((line = br.readLine()) != null) {
                Log.e(TAG," line "+line + " "+startStream+" "+startDecode);
                byte[] pText;
                if(line.contains("FlateDecode")){
                    startDecode = true;

                }
                if(line.equals("stream")){
                    startStream = true;
                    continue;
                }
                if(line.equals("endstream")){
                    startDecode = false;
                    startDecode = false;
                }

                if(startDecode && startStream){
                    Log.e(TAG, " inside decode");
                    pText = FLATEDecode(line.getBytes());
                }
                else pText = line.getBytes();
                String res = new String(pText,"UTF-8");
                text.append(res);
                text.append('\n');
                Log.e(TAG,res);
            }
            br.close();
        }
        catch (IOException e) {

        }
    }catch (Exception e){
        e.printStackTrace();
    }

    return text.toString();

解码代码:

    byte[] buf = new byte[1024];

    Inflater decompressor = new Inflater();
    decompressor.setInput(src);

    // Create an expandable byte array to hold the decompressed data
    ByteArrayOutputStream bos = new ByteArrayOutputStream(src.length);

    try {
        while (!decompressor.finished()) {
            int count = decompressor.inflate(buf);
            bos.write(buf, 0, count);
        }
    } catch (DataFormatException e) {
        decompressor.end();
        throw new RuntimeException(e);
    }
    decompressor.end();

    return bos.toByteArray();`

但是我收到了这个错误

Caused by: java.util.zip.DataFormatException: incorrect header check
java.util.zip.Inflater.inflateImpl(Native Method)
java.util.zip.Inflater.inflate(Inflater.java:237)
java.util.zip.Inflater.inflate(Inflater.java:214)

我知道我可以使用像 itextpdfbox 这样的库,但问题是这些库不适用于 bangla pdf 这是我的最终目标。这就是我尝试从头开始构建 pdf 内容提取器的原因。这是我从 pdf 获得的一些原始数据。我想对其进行解码以获取原始数据。

3 0 obj
<</Type/Page/Parent 2 0 R/Resources<</Font<</F1 5 0 R>>/ProcSet[/PDF/Text/ImageB/ImageC/ImageI] >>/MediaBox[ 0 0 612 792] /Contents 4 0 R/Group<</Type/Group/S/Transparency/CS/DeviceRGB>>/Tabs/S/StructParents 0>>
endobj
4 0 obj
<</Filter/FlateDecode/Length 126>>
stream
x�S�P����u�tQ0��SprqVp

【问题讨论】:

  • 我试过这个,但没有运气
  • 可能有几行......而且它不是基于行的格式,在流和端流之间。您正在做的事情(“从头开始构建 pdf 内容提取器”)是一个困难的策略。而是找出为什么“这些库不适用于bangla pdf”。一些 PDF 对文本提取“免疫”。使用 Adob​​e Reader 时可以提取文本吗?
  • 强调@Tilman 的第一点:使用字符读取操作(例如通过FileReader 或其他Reader 实现)读取PDF,然后应用getBytes 很可能会给您带来其他东西比原始字节,并且您用 '\n' 替换每个行尾只会使情况变得更糟... PDF 是二进制格式,因此请这样对待。
  • @Tilman,到目前为止,我已经看到这些库不支持像孟加拉语这样的印度语。这就是为什么我打算从头开始构建一个。而且PDF实际上并不是免疫,它只是不是“আমারসোনারসোনার”我得到“আমারসিানারবাাংলাআমমসামায়ভালবামি。” span>

标签: android pdf text-extraction deflate


【解决方案1】:

您不想在二进制数据上使用readLine()。一旦您读取了长度 (126) 和带有“流”的行,那么您想要读取 126 个二进制数据字节(在您的示例中以“x”开头)并准确提供充气。

【讨论】:

    猜你喜欢
    • 2021-08-31
    • 2015-09-21
    • 2013-03-06
    • 2015-05-29
    • 2015-09-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多