如何在java中的gzip中获取文件的文件名?

时间:2010-10-21 06:42:56

标签: java gzip

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文件上使用它。 任何替代品?

5 个答案:

答案 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库中看到这样做的方法。

http://www.gzip.org/zlib/rfc-gzip.html#specification

答案 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提供两种获取文件名的选项:

使用元数据(Java 7+示例代码)

 String filename = GzipUtils.getUnCompressedFilename("a_gunzipped_file.gz");

使用“惯例”

Log-Verbose

参考