簡體   English   中英

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

[英]How do i get a filename of a file inside a gzip in java?

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

因為我有點同意“Michael Borgwardt”對他的回復,但這並不完全正確,gzip文件規范包含一個存儲在gz文件頭中的可選文件名,遺憾的是沒有辦法(據我所知)在當前的java(1.6)中獲取該名稱。 如在openjdk中的getHeader方法中執行GZIPInputStream所見

他們跳過閱讀文件名

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

我已經修改了類GZIPInputStream來獲取gzip存檔中的可選文件名(我不確定我是否被允許這樣做)( 從這里下載原始版本 ),你只需要添加一個成員字符串文件名; 到類,並修改上面的代碼為:

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

它對我有用。

實際上,使用多個成員的GZIP文件格式允許指定原始文件名。 包含FLAG.FNAME FLAG的成員可以指定名稱。 我沒有在java庫中看到這樣做的方法。

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

按照上面的答案,這里有一個例子,它創建一個包含文件“myTest.csv”的文件“myTest.csv.gz”,注意你不能更改內部文件名,也不能添加更多文件進入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();

}

Apache Commons Compress提供了兩個獲取文件名的選項:

使用元數據(Java 7+示例代碼)

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

隨着“慣例”

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

參考

Gzip純粹是壓縮。 沒有存檔,只是壓縮文件的數據。

慣例是讓gzip將.gz附加到文件名,並使用gunzip刪除該擴展名。 所以, logfile.txt變得logfile.txt.gz壓縮時,再次logfile.txt時,它的解壓縮。 如果重命名該文件,則名稱信息將丟失。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM