int BUFFER_SIZE = 4096;
byte[] buffer = new byte[BUFFER_SIZE];
InputStream input = new GZIPInputStream(new FileInputStream("a_gunzipped_file.gz"));
OutputStream output = new FileOutputStream("current_output_name");
int n = input.read(buffer, 0, BUFFER_SIZE);
while (n >= 0) {
output.write(buffer, 0, n);
n = input.read(buffer, 0, BUFFER_SIZE);
}
}catch(IOException e){
System.out.println("error: \n\t" + e.getMessage());
}
使用上面的代码,我可以成功地提取gzip的内容,尽管提取的文件的文件名正如预期的那样始终是current_output_name
(我知道它,因为我在代码中声明它是这样的)。我的问题是我不知道如何在档案文件内部获取文件的文件名。
虽然java.util.zip提供了ZipEntry,但是我无法在gzip文件上使用它。 任何替代品?
答案 0 :(得分:8)
因为我有点同意“Michael Borgwardt”对他的回复,但这并不完全正确,gzip文件规范包含一个存储在gz文件头中的可选文件名,遗憾的是没有办法(就我而言)知道)在当前的java(1.6)中获取该名称。如在openjdk中方法getHeader中的GZIPInputStream的实现中所见
他们跳过阅读文件名
// Skip optional file name
if ((flg & FNAME) == FNAME) {
while (readUByte(in) != 0) ;
}
我修改了GZIPInputStream类以从gzip存档中获取可选文件名(我不确定是否允许我这样做)(download the original version from here),你只需要添加一个成员字符串文件名;到类,并修改上面的代码:
// Skip optional file name
if ((flg & FNAME) == FNAME) {
filename= "";
int _byte = 0;
while ((_byte= readUByte(in)) != 0){
filename += (char)_byte;
}
}
它对我有用。
答案 1 :(得分:3)
实际上,使用多个成员的GZIP文件格式允许指定原始文件名。包含FLAG.FNAME FLAG的成员可以指定名称。我没有在java库中看到这样做的方法。
答案 2 :(得分:0)
Gzip纯粹是压缩。 没有存档,它只是文件的数据,已压缩。
约定是gzip将.gz
附加到文件名,并使用gunzip删除该扩展名。因此,logfile.txt
在压缩时变为logfile.txt.gz
,在解压缩时再次变为logfile.txt
。如果重命名该文件,则名称信息将丢失。
答案 3 :(得分:0)
按照上面的答案,这里有一个例子,创建一个文件“myTest.csv.gz”,其中包含一个文件“myTest.csv”,注意你不能改变内部文件名,你不能将更多文件添加到gz文件中。
@Test
public void gzipFileName() throws Exception {
File workingFile = new File( "target", "myTest.csv.gz" );
GZIPOutputStream gzipOutputStream = new GZIPOutputStream( new FileOutputStream( workingFile ) );
PrintWriter writer = new PrintWriter( gzipOutputStream );
writer.println("hello,line,1");
writer.println("hello,line,2");
writer.close();
}
答案 4 :(得分:0)
Apache Commons Compress提供两种获取文件名的选项:
String filename = GzipUtils.getUnCompressedFilename("a_gunzipped_file.gz");
Log-Verbose