自动压缩过程有时会跳过文件
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 结果,它将然后再次调用 ZipFiles
(if
语句的第二个条件),以便您几乎同时拥有两个 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
.
我的应用程序的一部分以一系列 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 结果,它将然后再次调用 ZipFiles
(if
语句的第二个条件),以便您几乎同时拥有两个 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
.