我有一个zip文件,其中包含我要读取的9个文件。因此,我实现了以下功能:
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
,而在readLine
调用中不会返回null?
答案 0 :(得分:1)
每次迭代入口指针时,都会丢失入口指针,因为每个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()获取字节。
如果可以使用ZipFile对象(而不是ZipInputStream),则可以执行您要完成的任务。
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();
。