【问题标题】:C# : How to save a zip file every X filesC#:如何每 X 个文件保存一个 zip 文件
【发布时间】:2017-03-06 15:38:14
【问题描述】:

我有一个用 C# 编写的程序,它应该每 n 条记录(如 500 条)保存一个 zip 文件。

我的想法是使用 mod 运算符 (%) 并且操作的结果为零,然后写入文件。哪个好,但是:如果我有 520 条记录怎么办?我应该在第一个 zip 中写入 500 个文件,然后在第二个 zip 中写入 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 是一个数据表,其中包含文件系统上的所有文件路径。

zip 对象是基于 dotnetzip 库的对象。

【问题讨论】:

  • 首先这不起作用,因为您的 indexrow 只会在 0 和 1 之间反弹,因为您在循环中声明它。其次,你要做的是,在循环结束时(在它之外),如果 indexrow % 500 != 0,那么你知道你有一些挂起的文件,所以保存 zip 文件。另外,我以前没有使用过 dotnetzip,但是我假设您需要在每次保存后声明一个新的 ZipFile,因为它怎么知道删除您已经调用的所有文件 AddFile
  • 我不确定我是否理解,但如果我是对的,你想要的是在 indexrow = indexrow++; 之后检查类似 if (in_dt.Rows.Count - indexrow<500) { //create the second zip with the rest of files}; 的内容
  • @Pikoh 这根本行不通。如果我有 500 行,你的 if 语句将返回 true 499 次。
  • 当然。如果我把他说对了,这就是 op 想要的
  • @Pikoh 如果他有 520 个文件,他想创建 2 个 zip 文件。您将创建 500 个 zip 文件。我不认为这是他想要的。

标签: c#


【解决方案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,Grouping 属性为 0。

对于文件 500 - 520,Grouping 属性为 1。

【讨论】:

  • 似乎很有趣。只是一个问题,因为 in_dt 是来自 XML 文件的数据表,编译器说:“DataRowCollection 不包含‘选择’定义”。我应该用“AsEnumerable()”更改数据表吗?
  • 是的,很抱歉,我使用记事本编写代码并忘记了这一点,但是是的,你是对的:stackoverflow.com/questions/10855/linq-query-on-a-datatable - 使用 .AsEnumerable() 是正确的做法。我将编辑我的代码。
  • 有了这个答案,它就像一个魅力,我学到了一些新东西。谢谢!
  • 没问题,很高兴能帮助您学习新知识。
【解决方案2】:

你可能想做的是这样的:

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
}

这样,如果您运行类似 ths:zipFiles(520, 250) 的函数,您将拥有 2*250 的 zip 文件和 1*20 的剩余文件。你可能需要在Parts(地板/单元格)上做一些有价值的事情。

【讨论】:

    猜你喜欢
    • 2022-07-05
    • 1970-01-01
    • 2021-04-29
    • 2023-03-09
    • 2013-02-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多