在Java中读取压缩PDF文件的字节

3
当我尝试使用Java中的“read”函数从普通PDF文件中读取字节到字节数组时,字节数组将正确加载,并且大小与原始PDF文件相同。
Path file_path = Paths.get("D:\\Zip Test Client", "vadClient1.pdf");
    byte[] ByteArray= Files.readAllBytes(file_path);
    FileOutputStream fos = new FileOutputStream(new File("E:\\newFinalPDF.pdf"));

但是,当我从一个压缩文件夹中读取同一PDF文件的字节时,读取函数仅读取了8843个字节(原始大小为194471),其余的都是0。

zipFile = new ZipFile(new File("D:\\Zip test Server\\ZipTestFolderOnServer.zip"));
        long count = zipFile.size();
        Enumeration<? extends ZipEntry> entries = zipFile.entries();
        while(entries.hasMoreElements()){

            System.out.println("New File starting");
            ZipEntry zipEntry = entries.nextElement();
            System.out.println(zipEntry.getName());
            InputStream fis =  zipFile.getInputStream(zipEntry); 
            byte[] fileToBytes = new byte[(int)zipEntry.getSize()];


            FileOutputStream fos = new FileOutputStream(new File("E:\\ContentZipped_"   + zipEntry.getName()));
            fis.read(fileToBytes);
            fos.write(fileToBytes);
            fis.close();
            Thread.sleep(1000);
            --count;
        }

这种行为的解释是什么?
编辑1:- 我不需要Tika或POI等第三方集成。

这些测试文件是PDF文件有多相关? - Jongware
1
你正在调用 InputStream.read 并忽略了返回值 - 你似乎假设可以在单次调用 read 中读取所有数据。这是一个错误的假设。 - Jon Skeet
2
你可能没有完整地读取inputStream,需要一直读取直到fis.read返回-1,这意味着流的末尾。像你在第一个片段中所做的那样使用Files.readAllBytes,这样你就可以得到完整的文件。 - Jean-François Savard
1
我们没有必要试图纠正一段不代表您真实代码的代码。我已经说了你提供的代码有什么问题 - InputStream.read不能保证在返回之前读取所有请求的数据。如果您的实际代码在我列出的假设方面相同,那么这就是问题所在。如果您真的有一个循环,并且您正在调用read多次直到它返回-1表示流的结束,那么您应该更新您的问题以显示这一点。 - Jon Skeet
@JonSkeet 谢谢,你的建议起作用了。 :) - blackstar
显示剩余3条评论
2个回答

2

通过简化代码,使用以下代码复制zip条目中的内容,可以使其更少出错(并且更少占用内存):

try (InputStream fis =  zipFile.getInputStream(zipEntry)) {
    Files.copy(fis, Paths.get("E:\\ContentZipped_"   + zipEntry.getName()));
}

0

公共类SampleZipExtract {

public static void main(String[] args) {

    List<String> tempString = new ArrayList<String>();
    StringBuffer sbf = new StringBuffer();

    File file = new File("C:\\Users\\xxx\\Desktop\\abc.zip");
    InputStream input;
    try {

      input = new FileInputStream(file);
      ZipInputStream zip = new ZipInputStream(input);
      ZipEntry entry = zip.getNextEntry();

      BodyContentHandler textHandler = new BodyContentHandler();
      Metadata metadata = new Metadata();

      Parser parser = new AutoDetectParser();

      while (entry!= null){

            if(entry.getName().endsWith(".txt") || 
                       entry.getName().endsWith(".pdf")||
                       entry.getName().endsWith(".docx")){
          System.out.println("entry=" + entry.getName() + " " + entry.getSize());
                 parser.parse(input, textHandler, metadata, new ParseContext());
                 tempString.add(textHandler.toString());
            }
       }
       zip.close();
       input.close();

       for (String text : tempString) {
       System.out.println("Apache Tika - Converted input string : " + text);
       sbf.append(text);
       System.out.println("Final text from all the three files " + sbf.toString());
    } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (SAXException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (TikaException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

}


感谢您的回答。但我不需要任何第三方API。我会编辑原始帖子。 - blackstar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接