읽고 싶은 9개의 파일이 포함된 zip 파일이 있습니다. 그래서 다음 기능을 구현했습니다.
public static Map<String, BufferedReader> unzipFile(InputStream zippedFile) throws IOException {
ZipInputStream zipInputStream = new ZipInputStream(zippedFile);
HashMap<String, BufferedReader> result = new HashMap<>(9);
for (ZipEntry zipEntry = zipInputStream.getNextEntry(); zipEntry != null; zipEntry = zipInputStream.getNextEntry()) {
if (zipEntry.isDirectory()) {
continue;
}
result.put(zipEntry.getName(), new BufferedReader(new InputStreamReader(zipInputStream)));
}
return result;
}
동일한 클래스의 다른 서명(동일한 메소드 호출):
public static Map<String, BufferedReader> unzipFile(String zippedFile) throws IOException {
return unzipFile(new File(zippedFile));
}
public static Map<String, BufferedReader> unzipFile(File zippedFile) throws IOException {
return unzipFile(new FileInputStream(zippedFile));
}
내 생각은 Map
이 메서드에서 반환되는 값 을 가져 와서 내 코드의 다른 곳에서 읽을 수 있도록 하는 것이었습니다. 문제는 이 메서드 result.get("filename").readLine()
에서 for
루프 외부에서 호출할 때마다 null
.
다음은 이 방법에 대한 간단한 단위 테스트입니다. 현재 마지막 단계에서 실패하고 있습니다 Assert.assertNotNull
.
@Test
public void unzipFileTest() throws Exception {
Map<String, BufferedReader> result = FileHandlerUtility.unzipFile(TestUtil.FILE_SAMPLE_NAME);
Assert.assertNotNull(result);
Assert.assertEquals(result.size(), 9);
Assert.assertNotNull(result.get("Car.txt"));
Assert.assertNotNull(result.get("Client.txt"));
Assert.assertNotNull(result.get("Client.txt").readLine());
}
디버깅할 때 for
루프 내에서 파일의 내용을 가져올 수 있다는 것을 알았기 때문에 생성된 변수의 범위와 관련된 것이 있을 수 있습니다 . 하지만 이 zip 추출 방식과 콘텐츠를 가져와서 파싱하는 방식을 혼용하고 싶지는 않았습니다. 또한 추출된 파일을 디스크에 저장하고 나중에 다시 열고 싶지 않습니다.
그래서, 내가 어떻게이 문제를 채울 수 Map
와 BufferedReader
에 NULL을 반환하지 않을의 readLine
호출?
진입 포인터를 반복할 때마다 ZipInputStream 객체당 하나의 스트림만 허용되므로 진입 포인터를 잃게 됩니다.
try (ZipInputStream is = new ZipInputStream(Zippy.class.getResourceAsStream("file.zip"))) {
ZipEntry entry;
while ((entry = is.getNextEntry()) != null) {
if (!entry.isDirectory()) {
// do your logic here (get the entry name)
}
is.closeEntry();
}
}
closeEntry()
-Closes the current ZIP entry and positions the stream for reading the next entry.
getNextEntry() - Reads the next ZIP file entry and positions the stream at the beginning of the entry data.
기본적으로 주어진 시간에 하나의 항목만 열 수 있습니다.
따라서 현재 수행 중인 작업을 수행하려는 경우 할 수 있는 최선은 zip 항목의 이름을 저장하고 ZipInputStream을 반복하여 포인터를 올바른 위치로 이동한 다음 ZipInputStream.read()를 사용하여 가져올 수 있습니다. 바이트.
ZipInputStream 대신에 ZipFile 객체를 사용할 수 있다면 원하는 작업을 수행할 수 있습니다.
static void loadMap() throws IOException {
ZipFile file = new ZipFile("testzip.zip");
Enumeration<? extends ZipEntry> entries = file.entries();
while (entries.hasMoreElements()) {
ZipEntry entry = entries.nextElement();
if (!entry.isDirectory()) {
streamMap.put(entry.getName(), new BufferedReader(new InputStreamReader(file.getInputStream(entry))));
}
}
}
public static void main(String[] args) throws IOException {
loadMap();
Iterator<BufferedReader> iter = streamMap.values().iterator();
while (iter.hasNext()) {
BufferedReader reader = iter.next();
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
}
}
OUTPUT:
file 2: First line!
file 2: Second Line!
file 1: First line!
file 1 : Second Line!
BUILD SUCCESSFUL (total time: 0 seconds)
zip 파일 참조를 유지하고 file.close();
작업이 끝나면 호출하는 것을 기억해야 합니다.
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다