当我通过控制台给出zip文件夹路径时,我有一个程序。它将遍历文件夹中的每个项目(每个子项目、子项目的子项目等)。但是如果它遇到一个zip文件夹,它会忽略zip文件夹中的所有内容,我需要读取zip文件夹中的所有内容,包括文件。
以下是贯穿每个项目的方法:
public static String[] getLogBuffers(String path) throws IOException//path is given via console
{
String zipFileName = path;
String destDirectory = path;
BufferedInputStream errorLogBuffer = null;
BufferedInputStream windowLogBuffer = null;
String strErrorLogFileContents="";
String strWindowLogFileContents="";
String[] errorString=new String[2];
byte[] buffer = new byte[1024];
ZipInputStream zis = new ZipInputStream(new FileInputStream(zipFileName));
ZipEntry zipEntry = zis.getNextEntry();
while (zipEntry != null)
{
String filePath = destDirectory + "/" + zipEntry.getName();
System.out.println("unzipping" + filePath);
if (!zipEntry.isDirectory())
{
if (zipEntry.getName().endsWith("errorlog.txt"))
{
ZipFile zipFile = new ZipFile(path);
InputStream errorStream = zipFile.getInputStream(zipEntry);
BufferedInputStream bufferedInputStream=new BufferedInputStream(errorStream);
byte[] contents = new byte[1024];
System.out.println("ERRORLOG NAME"+zipEntry.getName());
int bytesRead = 0;
while((bytesRead = bufferedInputStream.read(contents)) != -1) {
strErrorLogFileContents += new String(contents, 0, bytesRead);
}
}
if (zipEntry.getName().endsWith("windowlog.txt"))
{ ZipFile zipFile = new ZipFile(path);
InputStream windowStream = zipFile.getInputStream(zipEntry);
BufferedInputStream bufferedInputStream=new BufferedInputStream(windowStream);
byte[] contents = new byte[1024];
System.out.println("WINDOWLOG NAME"+zipEntry.getName());
int bytesRead = 0;
while((bytesRead = bufferedInputStream.read(contents)) != -1) {
strWindowLogFileContents += new String(contents, 0, bytesRead);
}
}
}
zis.closeEntry();
zipEntry = zis.getNextEntry();
}
errorString[0]=strErrorLogFileContents;
errorString[1]=strWindowLogFileContents;
zis.closeEntry();
zis.close();
System.out.println("Buffers ready");
return errorString;
}
在父zip文件夹内访问的项目(我的控制台输出):
unzippingC:logFolders/logX3.zip/logX3/
unzippingC:logFolders/logX3.zip/logX3/Anan/
unzippingC:logFolders/logX3.zip/logX3/Anan/errorreports/
unzippingC:logFolders/logX3.zip/logX3/Anan/errorreports/2021-11-23_103518.zip
unzippingC:logFolders/logX3.zip/logX3/Anan/errorreports/errorlog.txt
unzippingC:logX3.zip/logX3/Anan/errorreports/version.txt
unzippingC:logFolders/logX3.zip/logX3/Anan/errorreports/windowlog.txt
正如你所看到的程序只去直到2021-11-23_103518.zip,并在另一条路径之后,但2021-11-23_103518.zip有孩子的项目(文件),我需要访问感谢任何帮助,谢谢
zip文件不是文件夹。虽然Windows将zip文件视为文件夹,但它不是文件夹。. zip文件是一个带有内部条目表的单个文件,每个条目包含压缩数据。
您读取的每个内部. zip文件都需要一个新的ZipFile或ZipInputStream。这是没有办法的。
您不应该创建新的ZipFile实例来读取相同的内容。压缩文件的条目。您只需要一个ZipFile对象。您可以使用its entries()方法查看它的条目,也可以使用ZipFile的getInputStream方法读取每个条目。
如果使用多个对象读取相同的zip文件会在Windows上遇到文件锁定问题,我不会感到惊讶。)
try (ZipFile zipFile = new ZipFile(path))
{
Enumeration<? extends ZipEntry> entries = zipFile.entries();
while (entries.hasMoreElements())
{
ZipEntry zipEntry = entries.nextElement();
if (zipEntry.getName().endsWith("errorlog.txt"))
{
try (InputStream errorStream = zipFile.getInputStream(zipEntry))
{
// ...
}
}
}
}
请注意,没有创建其他ZipFile或ZipInputStream对象。只有zipFile
读取并遍历文件。还要注意使用try with resources语句隐式关闭ZipFile和InputStream。
您不应该使用=
来构建字符串。这样做会创建大量中间字符串对象,这些对象必须进行垃圾收集,这可能会影响程序的性能。您应该将每个zip条目的InputStream包装在InputStreamReader中,然后使用该读取器的transferTo方法附加到保存组合日志的单个StringWriter。
String strErrorLogFileContents = new StringWriter();
String strWindowLogFileContents = new StringWriter();
try (ZipFile zipFile = new ZipFile(path))
{
Enumeration<? extends ZipEntry> entries = zipFile.entries();
while (entries.hasMoreElements())
{
ZipEntry zipEntry = entries.nextElement();
if (zipEntry.getName().endsWith("errorlog.txt"))
{
try (Reader entryReader = new InputStreamReader(
zipFile.getInputStream(zipEntry)),
StandardCharsets.UTF_8)
{
entryReader.transferTo(strErrorLogFileContents);
}
}
}
}
注意StandardCharset的使用。UTF_8。从字节创建字符串而不指定字符集几乎是不正确的。如果您不提供字符集,Java将使用系统的默认字符集,这意味着您的程序在Windows中的行为将不同于在其他操作系统上的行为。
如上所述,一个本身是内部zip文件的zip条目需要一个全新的ZipFile或ZipInputStream对象来读取它。我建议将条目复制到临时文件中,因为从另一个ZipInputStream读取ZipInputStream的速度很慢,然后在完成读取后删除临时文件。
try (ZipFile zipFile = new ZipFile(path))
{
Enumeration<? extends ZipEntry> entries = zipFile.entries();
while (entries.hasMoreElements())
{
ZipEntry zipEntry = entries.nextElement();
if (zipEntry.getName().endsWith(".zip"))
{
Path tempZipFile = Files.createTempFile(null, ".zip");
try (InputStream errorStream = zipFile.getInputStream(zipEntry))
{
Files.copy(errorStream, tempZipFile,
StandardCopyOption.REPLACE_EXISTING);
}
String[] logsFromZip = getLogBuffers(tempZipFile.toString());
strErrorLogFileContents.write(logsFromZip[0]);
strWindowLogFileContents.write(logsFromZip[1]);
Files.delete(tempZipFile);
}
}
}
最后,考虑为返回值创建一个有意义的类。字符串数组很难理解。调用者不会知道它总是恰好包含两个元素,也不会知道这两个元素是什么。自定义返回类型将非常短:
public class Logs {
private final String errorLog;
private final String windowLog;
public Logs(String errorLog,
String windowLog)
{
this.errorLog = errorLog;
this.windowLog = windowLog;
}
public String getErrorLog()
{
return errorLog;
}
public String getWindowLog()
{
return windowLog;
}
}
从Java 16开始,您可以使用记录来缩短声明:
public record Logs(String errorLog,
String windowLog)
{ }
无论您是使用记录还是写出类,您都可以在方法中使用它作为返回类型:
public static Logs getLogBuffers(String path) throws IOException
{
// ...
return new Logs(
strErrorLogFileContents.toString(),
strWindowLogFileContents.toString());
}
*Windows资源管理器shell将zip文件视为文件夹的做法是一个非常糟糕的用户界面。我知道我不是唯一一个这么想的人。它通常会让用户的事情变得更加困难,而不是更容易。
我想用Java编写一个GUI zip/unzip程序。该程序将能够压缩文件和目录/IES的任何组合,并解压缩一个或多个压缩文件。 现在我刚刚完成了GUI和zip Funtion。但是zip funtion似乎不能正常工作,产生的zip文件不知何故被破坏了。我找不到问题到底出在哪里。它似乎与函数或函数有关。 当我测试该程序时,输出如下: 归档:找不到test1.zip中央目录结束签名。要么这个文件不
问题内容: 我需要使用以下命令创建一个zip文件: 这可行,但是创建的zip文件会创建一个目录结构,将目录模仿为原始文件。我不需要很多额外的文件夹。 粗略浏览手册页或Google搜索时,我没有找到答案。 问题答案: 您可以使用。
我试图在ZIP文件内创建一个ZIP文件,以重新构建以前在内存中的zip结构,我在Java。 我失败了,因为我得到了一个错误的内部ZIP内创建的初始ZIP文件。文件已损坏。当试图打开它时,我得到一个“文件的意外结局”。 我得到了这个结构: -input.zip--InnerInput.zip 代码使用java Stack和Map在内存中解压。然后它创建input2.zip,内部nput.zip。 总
GitBook会读取 .gitignore,.bookignore,.ignore 文件来获取忽略的文件和目录的列表。 这些文件的格式,遵循和 .gitignore 同样的约定: # 这是一个注释 # 忽略文件test.md test.md # 忽略文件夹 "bin" 中的所有内容 bin/*
我已经阅读了前面的所有主题以及关于如何使用命令提示符的建议。但让我们来看看windows用户。 我正在使用GitHub桌面,只是从站点简单安装 我没有访问命令提示版Git的权限。我有.idea文件夹要排除在跟踪范围之外。知道怎么做吗?
我在settigns.xml文件中添加了代理配置,但Maven没有使用它,我通过使settings.xml文件无效来确认这一点。我运行maven install命令来更新设置和全局设置以指向正确的文件,仍然没有运气。我正在使用maven3.0.4。