Zip 파일 내에있는 파일에서 콘텐츠 읽기
zip 파일 내의 파일에서 내용을 읽고 추출하는 간단한 Java 프로그램을 만들려고합니다. 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();
}
}
}
각각에서 파일 콘텐츠를 얻는 방법이 궁금하다면 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이 있으면 원하는대로 읽을 수 있습니다.
Java 7부터 NIO Api는 Zip 또는 Jar 파일의 내용에 액세스하는 더 좋고 일반적인 방법을 제공합니다. 사실, 이제는 일반 파일과 똑같이 Zip 파일을 처리 할 수있는 통합 API입니다.
이 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));
});
}
자바 7에서
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);
}
});
}
}
의 조건으로 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
}
Tika가 컨테이너 파일을 처리하는 데 사용할 수있는 샘플 코드입니다. http://wiki.apache.org/tika/RecursiveMetadata
내가 말할 수 있듯이, 허용되는 솔루션은 중첩 된 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();
One advantage of this approach: InputStreams are passed as an arguments to methods that process them and those methods have a tendency to immediately close the input stream after they are done with it.
참고URL : https://stackoverflow.com/questions/15667125/read-content-from-files-which-are-inside-zip-file
'developer tip' 카테고리의 다른 글
| jQuery UI 자동 완성-마우스를 올리면 메뉴가 사라집니다. (0) | 2020.11.29 |
|---|---|
| / in vi 검색 및 바꾸기? (0) | 2020.11.29 |
| IntelliJ IDEA 렌더링 오류 (0) | 2020.11.29 |
| Android 팝업 창 닫기 (0) | 2020.11.29 |
| AudioRecord 개체가 초기화되지 않음 (0) | 2020.11.29 |