Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/330.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在java中获得gzip中的文件名?_Java_Gzip - Fatal编程技术网

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

如何在java中获得gzip中的文件名?,java,gzip,Java,Gzip,使用上面的代码,我可以成功地提取gzip的内容,尽管提取文件的文件名总是如预期的那样是当前的\u output\u name(我知道它是什么,因为我在代码中声明它是这样的)。我的问题是,当文件仍在归档文件中时,我不知道如何获取文件名 尽管java.util.zip提供了ZipEntry,但我无法在gzip文件上使用它。 还有别的选择吗 Gzip纯粹是压缩。没有存档,只是文件的数据,经过压缩 约定是gzip将.gz附加到文件名,gunzip将删除该扩展名。因此,logfile.txt在压缩时变为l

使用上面的代码,我可以成功地提取gzip的内容,尽管提取文件的文件名总是如预期的那样是
当前的\u output\u name
(我知道它是什么,因为我在代码中声明它是这样的)。我的问题是,当文件仍在归档文件中时,我不知道如何获取文件名

尽管java.util.zip提供了ZipEntry,但我无法在gzip文件上使用它。
还有别的选择吗

Gzip纯粹是压缩。没有存档,只是文件的数据,经过压缩


约定是gzip将
.gz
附加到文件名,gunzip将删除该扩展名。因此,
logfile.txt
在压缩时变为
logfile.txt.gz
,在解压缩时再次变为
logfile.txt
。如果重命名文件,名称信息将丢失。

实际上,GZIP文件格式使用多个成员,允许指定原始文件名。包括标志为FLAG.FNAME的成员可以指定名称。不过,我在java库中看不到这样做的方法

正如我有点同意“Michael Borgwardt”的回答,但这并不完全正确,gzip文件规范包含一个存储在gz文件头中的可选文件名,遗憾的是(据我所知)在当前java(1.6)中无法获得该名称。如openjdk中方法中GZIPInputStream的实现所示

他们跳过读取文件名

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());
    }
我已经修改了类GZIPInputStream以从gzip存档中获取可选文件名(我不确定是否允许我这样做)(),您只需要添加一个成员字符串文件名;,并将上述代码修改为:

// Skip optional file name
if ((flg & FNAME) == FNAME) {
      while (readUByte(in) != 0) ;
}

这对我很有用。

根据上面的答案,下面是一个创建文件“myTest.csv.gz”的示例,其中包含一个文件“myTest.csv”,请注意,您不能更改内部文件名,也不能将更多文件添加到gz文件中

 // Skip optional file name
 if ((flg & FNAME) == FNAME) {
      filename= "";
      int _byte = 0;
      while ((_byte= readUByte(in)) != 0){
           filename += (char)_byte;
      }
 }

Apache Commons Compress提供了两种获取文件名的选项:

使用元数据(Java7+示例代码) “公约” 工具书类
  • 另见:

哦,对不起,我的愚蠢,我的错,我没有先读到关于gz的书。谢谢你指出这并不完全正确。如果在2.3.1中检查RFC for GZIP(),则第4字节的第4位用于指定原始文件名。-1不完全正确,GZIP格式可以保存原始文件名和时间戳。只需查看GNU gzip/gunzip的手册页,查看压缩和解压缩的
--name
--no name
选项。是的,这个答案完全错误。Gzip在压缩流中保存名称和时间戳。您必须明确说明是否不使用-n选项保存此信息。
@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();

}
try ( //
     GzipCompressorInputStream gcis = //
         new GzipCompressorInputStream( //
             new FileInputStream("a_gunzipped_file.gz") //
         ) //
    ) {
      String filename = gcis.getMetaData().getFilename();
    }
 String filename = GzipUtils.getUnCompressedFilename("a_gunzipped_file.gz");