2017-03-06 18 views
1

我有一個用C#編寫的程序,它應該每n個記錄(如500)保存一個zip文件。C#:如何保存每個X文件的zip文件

我的想法是使用mod運算符(%),並且操作的結果爲零,然後寫入文件。這很好,但是:如果我有520條記錄怎麼辦?我應該在第一個zip中寫入500個文件,然後在第二個文件中寫入20個文件。

這裏的代碼:

 using (ZipFile zip = new ZipFile()) 
     { 
      zip.CompressionLevel = Ionic.Zlib.CompressionLevel.Level8; 
      zip.CompressionMethod = CompressionMethod.Deflate; 
      int indexrow = 0; 
      foreach(DataRow row in in_dt.Rows) 
      { 
       zip.AddFile(row["Path"].ToString(),"prova123"); 
       if(indexrow % 500 == 0) 
       { 
        using (var myZipFile = new FileStream("c:\\tmp\\partial_"+indexrow.ToString()+".zip", FileMode.Create)) 
        { 
         zip.Save(myZipFile); 
        } 
        indexrow = indexrow++; 
       } 
      } 
     } 
    } 

in_dt是包含在文件系統中的所有文件路徑的DataTable。

zip對象是基於dotnetzip庫的對象。

+0

首先,這是行不通的,因爲你的索引將在0和1之間反彈,因爲你在循環中聲明它。其次,你想要做的是,在循環結束時(在它之外),如果indexrow%500!= 0,那麼你知道你有一些掛起的文件,所以保存壓縮文件。另外,我之前沒有使用過dotnetzip,但是我會假設你需要在每次保存後聲明一個新的'ZipFile',因爲它怎麼會知道你已經刪除了所有你稱爲'AddFile'的文件? – dman2306

+0

我不確定我是否理解,但如果我是正確的你想要的是在'indexrow = indexrow ++之後;'檢查類似'if(in_dt.Rows.Count - indexrow <500){//創建第二個zip其餘的文件};' – Pikoh

+0

@Pikoh根本不起作用。如果我有500行,你的if語句將返回真499次。 – dman2306

回答

1

我會使用LINQ的這個問題:

// Define the group size 
const int GROUP_SIZE = 500; 

// Select a new object type that encapsulates the base item 
// and a new property called "Grouping" that will group the 
// objects based on their index relative to the group size 
var groups = in_dt 
    .Rows 
    .AsEnumerable() 
    .Select(
     (item, index) => new { 
      Item = item, 
      Index = index, 
      Grouping = Math.Floor(index/GROUP_SIZE) 
     } 
    ) 
    .GroupBy(item => item.Grouping) 
; 

// Loop through the groups 
foreach (var group in groups) { 
    // Generate a zip file for each group of files 
} 

對於文件0至499,分組屬性爲0。

對於文件500 - 520,分組屬性是1

+1

看起來很有趣。因爲in_dt是一個來自XML文件的數據表達式,編譯器說:「DataRowCollection不包含'select'定義」。我應該用「AsEnumerable()」更改數據表嗎? – LuciferSam

+0

是的,對不起,我正在使用記事本編寫代碼並忘記了這一點,但是,是的,你是對的:http://stackoverflow.com/questions/10855/linq-query-on-a-datatable - using .AsEnumerable()是正確的事情。我將編輯我的代碼。 – peaceoutside

+1

有了這個答案,它就像一個魅力,我學到了新的東西。 謝謝! – LuciferSam

0

什麼你可能想要做的是這樣的:

zipFiles(File[] Files, int MaxFilesInZip) 
{ 
int Parts = Files.Count/MaxFilesInZip; 
int Remaning = Files.Count % MaxFilesInZip; 
for(int i = 0; i < Parts; i++) 
    //New zip 
    for(int u = 0; u < MaxFilesInZip; u++) 
     //Add Files[i*MaxFilesInZip + u] 
//New Zip 
//Add 'Remaning' amount of files 
} 

如果你運行像部份的功能是這樣的:zipFiles(520, 250),你將有2個* 250 ZIP文件和1 * 20,其剩餘。你可能需要在Parts(Floor/Celling)上工作。