Kettle6壓縮文件步驟詳解

1、前言微信

本文將對Kettle6中壓縮文件步驟(英文原名:Zip File)進行詳細說明。顧名思義,該步驟實現對源文件的壓縮處理,並能夠完成目標文件夾建立、壓縮源文件處理等配套功能。使用時注意如下兩個限制:spa

  • 壓縮源文件、目標文件的名稱都必須來自數據流中的字段.net

  • 只支持zip壓縮翻譯

本文附錄解釋如何經過修改源碼增長gzip功能。3d

 

2、說明blog

壓縮文件步驟的屬性對話框以下圖1所示:ip

                圖1.     ci


下面經過一個表格逐項解釋每個對話框中字段的含義。get

序號input

名稱

含義

1

建立目標文件夾

若是選中,那麼在壓縮文件存放的文件夾不存在時,Kettle將自動建立。若是未選中,務必確保目標文件夾已存在,不然將拋出異常ZipFile.Error.TargetParentFolderNotExists

2

覆蓋目標文件

實際上,這裏應該翻譯爲「添加到已有文件」更爲合理。其真實含義是,若是選中,那麼若是壓縮目標文件已經存在,Kettle僅在已有文件中增長文件條目,從而完成zip歸檔功能。

3

添加zip文件名到結果集

將最終文件名稱推入輸出行集。

4

源文件名字段

壓縮文件的來源。整個步驟的處理流程是,從輸入行集的源文件名字段中取出一個值(設爲A),從輸入行集的目標文件名字段中取出一個值(設爲B),而後將A文件壓縮到B中。

5

目標文件名字段

輸入行集中存儲壓縮目標文件名的字段名稱。

6

保留源文件夾

選中時,7纔可用。具體含義是,若是選中,那麼最終壓縮文件中,不只存儲了源文件名稱,並且也保留了源文件的文件目錄結構。具體的目錄結構,來自於第7步設置字段的值。

7

源文件夾字段名

設置壓縮文件中目錄結構的來源。僅在第6步選中時有效。

8

壓縮以後

壓縮以後,有3個選擇。

  • 什麼也不作

  • 移動源文件:選擇此項,第9步纔可用。意思是壓縮完源文件後將其移動到第9步指定的目標文件夾。

  • 刪除源文件:壓縮後將源文件刪除。不過這個選項有bug。一旦文件較多,就會報異常。具體解決辦法參照附錄。

9

移動到的文件夾名稱

包含目標文件夾的字段名稱。

 

 

3、附錄

主要代碼解釋以下:

  • 包:org.pentaho.di.trans.steps.zipfile

  • 元數據類:ZipFileMeta

  • 運行數據類:ZipFileData

  • 執行過程類:ZipFile

下面解釋兩個源碼改進辦法。

1.如何解決壓縮後刪除文件的異常?

ZipFile類中有一個processFile方法,用於實現壓縮後的處理。其中:

case ZipFileMeta.OPERATION_TYPE_DELETE:

用於實現壓縮後刪除源文件。

產生異常的緣由在於文件關閉前刪除了文件,因此只要在文件關閉後刪除便可。具體代碼就一句:

if (data.sourceFile != null)

                   data.sourceFile.close();


修改後的結果以下圖2所示:

   圖2.

 

2.如何增長gzip壓縮功能?

ZipFile類中有一個processRow方法,用於處理每個壓縮請求。其中約224行處調用了一個zipFile方法,用於實現對文件的zip壓縮。就在此處能夠增長一個自定義邏輯,用於實現gzip壓縮。個人邏輯是根據用戶指定目標文件的擴展名來判斷,若是擴展名是gz,那麼就採用gzip壓縮,不然仍是採用原有zip壓縮。因此,這裏修改後的代碼以下圖3所示:

圖3.


gzipFile方法是本人新增,用於實現gzip功能,代碼以下:

privatevoidgzipFile() throwsKettleException {

        StringlocalrealZipfilename = KettleVFS.getFilename(data.zipFile);

        booleanupdateZip = false;

        byte[] buffer = null;

        OutputStreamdest= null;

        BufferedOutputStreambuff= null;

        GZIPOutputStreamgzout= null;

        InputStreamin = null;

 

        try {

            if (log.isDebug()) {

                log.logDebug("GZipFileThreadName:"+ Thread.currentThread().getName() + " "

                        +Thread.currentThread().getId());

            }

            updateZip = (data.zipFile.exists() && meta.isOverwriteZipEntry());

            if (updateZip) {

                FilefileZip= getFile(localrealZipfilename);

                fileZip.delete();

            }

            // Prepare GZip File

            buffer = newbyte[18024];

            dest = KettleVFS.getOutputStream(localrealZipfilename,false);

            buff = new BufferedOutputStream(dest);

            gzout = new GZIPOutputStream(buff);

            // Associate a file input stream for the current file

            in = KettleVFS.getInputStream(data.sourceFile);

            intlen;

            while ((len = in.read(buffer)) > 0) {

                gzout.write(buffer, 0, len);

            }

            gzout.finish();

        }catch(Exception e) {

            thrownewKettleException(BaseMessages.getString(PKG, "ZipFile.ErrorCreatingZip"), e);

        }finally{

            try {

                if (in != null) {

                    // Close the current file input stream

                    in.close();

                }

                if (gzout != null) {

                    // Close the GZIPOutPutStream

                    gzout.flush();

                    // gzout.closeEntry();

                    gzout.close();

                }

                if (buff != null) {

                    buff.close();

                }

                if (dest != null) {

                    dest.close();

                }

            }catch(Exception e) { /* Ignore */

            }

        }

 

    }


本文分享自微信公衆號 - Kettle博士(gh_f656c3d7ba54)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。

相關文章
相關標籤/搜索