自动压缩过程有时会跳过文件

Automated zip process sometimes skips files

我的应用程序的一部分以一系列 CSV 文件导出数据,添加附注,然后将所有这些数据打包到受密码保护的 zip 文件中,以备发送。

这是执行压缩的相关代码。

private bool ZipFiles(string zipfile, string filename, string password)
{
    string arguments = string.Format(@"a -tzip ""{0}"" ""{1}"" -p{2}", zipfile, filename, password);

    ProcessStartInfo startInfo = new ProcessStartInfo(_zipExePath)
    {
        UseShellExecute = false,
        RedirectStandardError = true,
        RedirectStandardInput = true,
        RedirectStandardOutput = true,
        CreateNoWindow = true,
        ErrorDialog = false,
        Arguments = arguments,
        WindowStyle = ProcessWindowStyle.Hidden
    };

    try
    {
        Process.Start(startInfo);
    }
    catch (Exception ex)
    {
        Log.Error("Zip Process Failed", ex);
        return false;
    }

    return true;
}

它的名字是这样的:

string notePath = CreateNote(task);
string zipfile = _outputPath + "\" task.TaskNumber + ".zip";
string filewildcard = _outputPath + "\Data\*.csv";

if (!ZipFiles(zipfile, filewildcard, task.Password) || !ZipFiles(zipfile, notePath, task.Password))
{
    Log.Error("Failed to created zip archive for Id " + task.TaskID);
    hasError = true;
}

大多数时候,这没有问题。但是,存在一个间歇性问题,导致某些目标文件未最终出现在存档中。大多数情况下,当发生这种情况时,会包含注释,但 none 的数据。极少数情况下,存档中根本不包含任何文件。

失败的任务似乎没有任何统一因素。有时任务无法生成正确的 zip,然后在重置后,可以再次 运行 并正确创建 zip。

每当我尝试使用调试器逐步执行此代码以重现问题时,文件都会按预期压缩。我已经这样做了很多次,在调试器中它似乎每次都能正常工作。

当文件没有全部压缩时,不会记录任何错误。

所以我认为这可能是一个时间问题 - 实际上代码在磁盘完成输出数据之前到达了 zip 部分。我在生成数据的代码和我发布的代码之间添加了等待

Thread.Sleep(500);

这并没有解决问题。所以我把它做得越来越长。现在有十分钟的暂停,这个问题仍然存在。

我不知道是什么原因造成的。还有人有其他想法吗?

我认为问题可能是由这段代码引起的:

if (!ZipFiles(zipfile, filewildcard, task.Password) || !ZipFiles(zipfile, notePath, task.Password))
{
    Log.Error("Failed to created zip archive for Id " + task.TaskID);
    hasError = true;
}

if 语句被执行时,它首先调用 ZipFiles,它将 return 几乎立即得到 true 结果,它将然后再次调用 ZipFilesif 语句的第二个条件),以便您几乎同时拥有两个 zip 实用程序实例 运行,使用相同的 zip 文件名。他们可能会踩到彼此的脚趾。

您可以尝试添加对 Process.WaitForExit 的调用以确保第一个实例在开始第二个实例之前完成:

try
{
    Process p = Process.Start(startInfo);
    p.WaitForExit();
}
catch (Exception ex)
{
    Log.Error("Zip Process Failed", ex);
    return false;
}

此代码中的 try/catch 不会捕获 zip 实用程序中发生的任何异常。它将捕获 启动 可执行文件时发生的任何异常。您可能希望检查 p.ExitCode 的值以查看实用程序是否有任何问题,如果有,return false.