none
如何合併個巨大文字檔 RRS feed

  • 問題

  • 本人剛剛開始使用C#來開發程式,目前遇到一個瓶頸,我有100多個檔案都是文字檔,要把他合併成一個文字檔案,一個檔案平均100MB左右,合起來都超過3GB,每次合併到 700MB左右就會有記憶體不足的問題,以下是我的程式碼片段,不知道各位前輩有沒有好的解法?

     

                for (int i = 0; i < intFileCount; i++)
                {
                    string strCorrentFile = workpath + "\\" + lstFile.ItemsIdea.ToString();
                    objReader = new StreamReader(strCorrentFile);
                    objReader.ReadLine();
                    objReader.ReadLine();
                    strTemp = objReader.ReadToEnd();

                    objReader.Close();

                   
                    objWriter = File.AppendText(saveFileDialog1.FileName);
                    objWriter.WriteLine();
                    objWriter.WriteLine();
                    objWriter.Write(strTemp);


                    objWriter.Close();
                }

    2006年9月29日 上午 07:28

解答

  • 字串上限也只到 2 GB,若是你是英數的 700 MB ,換算為 Unicode ,也有 1.5 GB ,在加上程式其他部分使用的記憶體,爆掉也不稀奇吧?

    純複製合併,請不要使用字串處理函數,因為在 IO 時,會做 ANSI <-> Unicode 轉換,且不要使用 & 這種耗資源的方式。

    請使用二進位檔方式處理,每 32 kb 為單位,從來源讀出,寫入至目的檔即可。

    2006年9月29日 下午 12:28

所有回覆

  • 有一個偷懶的方法,不知道是否可以

    以下是Dos Command "Copy的說明",請在Console mode下打copy/?就可以看到以下說明:

    將一些檔案複製到另一個位置。

    COPY [/V] [/N] [/Y | /-Y] [/Z] [/A | /B ] source [/A | /B]
         [+ source [/A | /B] [+ ...]] [destination [/A | /B]]

       source        指定要複製的檔案。
        /A           指定一個 ASCII 文字檔案。
        /B           指定一個二位元檔案。
       destination   為新檔案指定目錄及(或) 檔案名稱。
        /V           確認新檔案是否正確寫入。
        /N           使用短檔名來複製非 8.3 名稱的檔案
                     (如果可用的話)。
        /Y           不顯示覆寫現存
                     目的檔案的確認提示。
        /-Y          顯示覆寫現存目的
                     檔案的確認提示。
        /Z           在可重新啟動模式中複製網路檔案。

    參數  /Y 可以預先設定在 COPYCMD 環境變數中。
    這可能會覆寫命令列中的 /-Y。預設值是
    顯示覆寫確認提示,除非 COPY 命令是從
    批次指令檔中執行。

    不過我也不知道Windows要是連續合併那麼多檔案會不會掛掉就是了

    2006年9月29日 上午 10:02
  •             for (int i = 0; i < intFileCount; i++)
                {
                    string strCorrentFile = workpath + "\\" + lstFile.Items.ToString();
                    objReader = new StreamReader(strCorrentFile);
                    objReader.ReadLine();
                    objReader.ReadLine();
                    strTemp = objReader.ReadToEnd();

                    objReader.Close();

                    objReader.Dispose();

                    objReader = null;

                   
                    objWriter = File.AppendText(saveFileDialog1.FileName);
                    objWriter.WriteLine();
                    objWriter.WriteLine();
                    objWriter.Write(strTemp);

                    objWriter.Close();

                    objWriter .Dispose();

                    objWriter = null;

                    strTemp  = null;
                }

    2006年9月29日 上午 11:02
  • 字串上限也只到 2 GB,若是你是英數的 700 MB ,換算為 Unicode ,也有 1.5 GB ,在加上程式其他部分使用的記憶體,爆掉也不稀奇吧?

    純複製合併,請不要使用字串處理函數,因為在 IO 時,會做 ANSI <-> Unicode 轉換,且不要使用 & 這種耗資源的方式。

    請使用二進位檔方式處理,每 32 kb 為單位,從來源讀出,寫入至目的檔即可。

    2006年9月29日 下午 12:28
  • 因為每個檔案還要做一些字串的處理,

    這樣還可以用二進位檔方式處理嗎?

    還是有可以使用buffer 的方式嗎?

    2006年9月29日 下午 03:46
  • 使用 Copy 指令來合併文字檔,會有一個現象,就是合併後的檔案最後面會多一碼,如下圖:

    http://ser8.imgdump.net/images/01092007/s8_378737d1b56b16e.gif

    要解決這個方式請加上 /B 這個參數,就可以解決了~~

    例如:copy 1.txt + 2.txt 3.txt /B 

    給有需要的人參考 ^^

     

    2007年1月10日 上午 03:36
  • 還是可以,但是 Byte() <-> String 要自己用 Encoding 處理。
    2007年1月10日 上午 03:46