Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/396.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 从Zip文件中的文件读取内容_Java_Zip_Extract_Apache Tika - Fatal编程技术网

Java 从Zip文件中的文件读取内容

Java 从Zip文件中的文件读取内容,java,zip,extract,apache-tika,Java,Zip,Extract,Apache Tika,我试图创建一个简单的java程序,从zip文件中读取和提取文件内容。Zip文件包含3个文件(txt、pdf、docx)。我需要阅读所有这些文件的内容,为此我正在使用ApacheTika 有人能帮我实现这个功能吗。到目前为止,我已经试过了,但没有成功 代码片段 public class SampleZipExtract { public static void main(String[] args) { List<String> tempString =

我试图创建一个简单的java程序,从zip文件中读取和提取文件内容。Zip文件包含3个文件(txt、pdf、docx)。我需要阅读所有这些文件的内容,为此我正在使用ApacheTika

有人能帮我实现这个功能吗。到目前为止,我已经试过了,但没有成功

代码片段

public class 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();
        }
    }
}
public类SampleZipExtract{
公共静态void main(字符串[]args){
List tempString=new ArrayList();
StringBuffer sbf=新的StringBuffer();
File File=新文件(“C:\\Users\\xxx\\Desktop\\abc.zip”);
输入流输入;
试一试{
输入=新文件输入流(文件);
ZipInputStream zip=新的ZipInputStream(输入);
ZipEntry entry=zip.getNextEntry();
BodyContentHandler textHandler=新的BodyContentHandler();
元数据=新元数据();
Parser Parser=new AutoDetectParser();
while(条目!=null){
if(entry.getName().endsWith(“.txt”)||
entry.getName().endsWith(“.pdf”)||
entry.getName().endsWith(“.docx”)){
System.out.println(“entry=“+entry.getName()+”+entry.getSize());
parse(输入,textHandler,元数据,新的ParseContext());
add(textHandler.toString());
}
}
zip.close();
input.close();
for(字符串文本:tempString){
System.out.println(“ApacheTika-转换后的输入字符串:“+text”);
附加(文本);
System.out.println(“所有三个文件的最终文本”+sbf.toString());
}catch(filenotfounde异常){
//TODO自动生成的捕捉块
e、 printStackTrace();
}捕获(IOE异常){
//TODO自动生成的捕捉块
e、 printStackTrace();
}捕获(SAXE异常){
//TODO自动生成的捕捉块
e、 printStackTrace();
}渔获物(Tikae){
//TODO自动生成的捕捉块
e、 printStackTrace();
}
}
}

由于
中的条件,而
中的循环可能永远不会中断:

while (entry != null) {
  // If entry never becomes null here, loop will never break.
}
您可以尝试以下操作,而不必在此处检查
null

ZipEntry entry = null;
while ((entry = zip.getNextEntry()) != null) {
  // Rest of your code
}

如果您想知道如何从每个
ZipEntry
中获取文件内容,实际上非常简单。下面是一个示例代码:

public static void main(String[] args) throws IOException {
    ZipFile zipFile = new ZipFile("C:/test.zip");

    Enumeration<? extends ZipEntry> entries = zipFile.entries();

    while(entries.hasMoreElements()){
        ZipEntry entry = entries.nextElement();
        InputStream stream = zipFile.getInputStream(entry);
    }
}
publicstaticvoidmain(字符串[]args)引发IOException{
ZipFile-ZipFile=新的ZipFile(“C:/test.zip”);

枚举可用于让Tika为您处理容器文件的示例代码。


据我所知,公认的解决方案不适用于存在嵌套zip文件的情况。Tika也会处理此类情况。

我实现这一点的方法是创建ZipInputStream包装类,该类将处理仅提供当前条目流的内容:

包装器类:

public class ZippedFileInputStream extends InputStream {

    private ZipInputStream is;

    public ZippedFileInputStream(ZipInputStream is){
        this.is = is;
    }

    @Override
    public int read() throws IOException {
        return is.read();
    }

    @Override
    public void close() throws IOException {
        is.closeEntry();
    }
}

信息技术的使用:

    ZipInputStream zipInputStream = new ZipInputStream(new FileInputStream("SomeFile.zip"));

    while((entry = zipInputStream.getNextEntry())!= null) {

     ZippedFileInputStream archivedFileInputStream = new ZippedFileInputStream(zipInputStream);

     //... perform whatever logic you want here with ZippedFileInputStream 

     // note that this will only close the current entry stream and not the ZipInputStream
     archivedFileInputStream.close();

    }
    zipInputStream.close();

这种方法的一个优点是:InputStreams作为参数传递给处理它们的方法,这些方法在处理完输入流后会立即关闭输入流。

从Java 7开始,NIO Api提供了一种更好、更通用的访问Zip或Jar文件内容的方法IEDAPI,允许您像处理普通文件一样处理Zip文件

要在此API中提取zip文件中包含的所有文件,请执行以下操作:

在Java 8中:

private void extractAll(URI fromZip, Path toDirectory) throws IOException{
    FileSystems.newFileSystem(fromZip, Collections.emptyMap())
            .getRootDirectories()
            .forEach(root -> {
                // in a full implementation, you'd have to
                // handle directories 
                Files.walk(root).forEach(path -> Files.copy(path, toDirectory));
            });
}
private void extractAll(URI fromZip, Path toDirectory) throws IOException{
    FileSystem zipFs = FileSystems.newFileSystem(fromZip, Collections.emptyMap());

    for(Path root : zipFs.getRootDirectories()) {
        Files.walkFileTree(root, new SimpleFileVisitor<Path>() {
            @Override
            public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) 
                    throws IOException {
                // You can do anything you want with the path here
                Files.copy(file, toDirectory);
                return FileVisitResult.CONTINUE;
            }

            @Override
            public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) 
                    throws IOException {
                // In a full implementation, you'd need to create each 
                // sub-directory of the destination directory before 
                // copying files into it
                return super.preVisitDirectory(dir, attrs);
            }
        });
    }
}
在java 7中:

private void extractAll(URI fromZip, Path toDirectory) throws IOException{
    FileSystems.newFileSystem(fromZip, Collections.emptyMap())
            .getRootDirectories()
            .forEach(root -> {
                // in a full implementation, you'd have to
                // handle directories 
                Files.walk(root).forEach(path -> Files.copy(path, toDirectory));
            });
}
private void extractAll(URI fromZip, Path toDirectory) throws IOException{
    FileSystem zipFs = FileSystems.newFileSystem(fromZip, Collections.emptyMap());

    for(Path root : zipFs.getRootDirectories()) {
        Files.walkFileTree(root, new SimpleFileVisitor<Path>() {
            @Override
            public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) 
                    throws IOException {
                // You can do anything you want with the path here
                Files.copy(file, toDirectory);
                return FileVisitResult.CONTINUE;
            }

            @Override
            public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) 
                    throws IOException {
                // In a full implementation, you'd need to create each 
                // sub-directory of the destination directory before 
                // copying files into it
                return super.preVisitDirectory(dir, attrs);
            }
        });
    }
}
private void extractAll(URI fromZip,指向目录的路径)引发IOException{
FileSystem zipFs=FileSystems.newFileSystem(fromZip,Collections.emptyMap());
for(路径根:zipFs.getRootDirectory()){
walkFileTree(根目录,新的SimpleFileVisitor(){
@凌驾
公共文件VisitResult visitFile(路径文件,基本文件属性属性属性)
抛出IOException{
//你可以用这里的路径做任何你想做的事情
文件。复制(文件,到目录);
返回FileVisitResult.CONTINUE;
}
@凌驾
公共文件VisitResult preVisitDirectory(路径目录,基本文件属性属性属性)
抛出IOException{
//在完整的实现中,您需要创建
//之前的目标目录的子目录
//将文件复制到其中
返回super.preVisitDirectory(dir,attrs);
}
});
}
}

我就是这样做的,记得更改url或zip文件 jdk 15

import java.io.FileNotFoundException;
导入java.io.FileOutputStream;
导入java.io.IOException;
导入java.net.MalformedURLException;
导入java.net.URL;
导入java.util.Scanner;
导入java.util.stream.stream;
导入java.util.zip.ZipEntry;
导入java.util.zip.ZipFile;
导入java.io.*;
导入java.util.*;
导入java.nio.file.path;
班长{
publicstaticvoidmain(字符串[]args)引发畸形的DurLexException、FileNotFoundException、IOException{
字符串url,kfile;
扫描仪GETW=新扫描仪(System.in);
System.out.println(“请粘贴Url:”;
url=getkw.nextLine();
System.out.println(“请输入要另存为的文件名::”;
kfile=getkw.nextLine();
getkw.close();
Main Dinit=新Main();
System.out.println(Dinit.dloader(url,kfile));
ZipFile香草=新ZipFile(新文件(“Vanilla.zip”);

枚举为什么不直接将zip文件传递给ApacheTika?然后它将调用为zip中的每个文件提供的递归解析器,这样您就不必做任何特殊的事情了!这就是我想知道的