我正在尝试创建一个简单的java程序,它从zip文件中的文件中读取和提取内容。 Zip文件包含3个文件(txt,pdf,docx)。我需要阅读所有这些文件的内容,我正在使用 Apache Tika 来实现此目的。
有人可以帮助我实现这一功能。到目前为止我已经尝试了这个但没有成功
代码段
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();
}
}
}
答案 0 :(得分:143)
如果您想知道如何从每个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);
}
}
一旦你有了InputStream,你可以随意阅读它。
答案 1 :(得分:35)
从Java 7开始,NIO Api提供了一种更好,更通用的方式来访问Zip或Jar文件的内容。实际上,它现在是一个统一的API,允许您像普通文件一样处理Zip文件。
为了提取此API中zip文件中包含的所有文件,您可以这样做:
在Java 8中:
qproperty-iconSize: 24px;
在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));
});
}
答案 2 :(得分:10)
由于while
中的条件,循环可能永远不会中断:
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
}
答案 3 :(得分:3)
您可以使用示例代码让Tika为您处理容器文件。 http://wiki.apache.org/tika/RecursiveMetadata
从我可以告诉的形式,接受的解决方案不适用于存在嵌套zip文件的情况。然而,蒂卡也将照顾这种情况。
答案 4 :(得分:2)
我实现这一目标的方法是创建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作为参数传递给处理它们的方法,并且这些方法在完成后立即关闭输入流。
答案 5 :(得分:0)
我是这样做的,记得更改 url 或 zip 文件 JDK 15
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Scanner;
import java.util.stream.Stream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.io.*;
import java.util.*;
import java.nio.file.Paths;
class Main {
public static void main(String[] args) throws MalformedURLException,FileNotFoundException,IOException{
String url,kfile;
Scanner getkw = new Scanner(System.in);
System.out.println(" Please Paste Url ::");
url = getkw.nextLine();
System.out.println("Please enter name of file you want to save as :: ");
kfile = getkw.nextLine();
getkw.close();
Main Dinit = new Main();
System.out.println(Dinit.dloader(url, kfile));
ZipFile Vanilla = new ZipFile(new File("Vanilla.zip"));
Enumeration<? extends ZipEntry> entries = Vanilla.entries();
while(entries.hasMoreElements()){
ZipEntry entry = entries.nextElement();
// String nextr = entries.nextElement();
InputStream stream = Vanilla.getInputStream(entry);
FileInputStream inpure= new FileInputStream("Vanilla.zip");
FileOutputStream outter = new FileOutputStream(new File(entry.toString()));
outter.write(inpure.readAllBytes());
outter.close();
}
}
private String dloader(String kurl, String fname)throws IOException{
String status ="";
try {
URL url = new URL("URL here");
FileOutputStream out = new FileOutputStream(new File("Vanilla.zip")); // Output File
out.write(url.openStream().readAllBytes());
out.close();
} catch (MalformedURLException e) {
status = "Status: MalformedURLException Occured";
}catch (IOException e) {
status = "Status: IOexception Occured";
}finally{
status = "Status: Good";}
String path="\\tkwgter5834\\";
extractor(fname,"tkwgter5834",path);
return status;
}
private String extractor(String fname,String dir,String path){
File folder = new File(dir);
if(!folder.exists()){
folder.mkdir();
}
return "";
}
}