首页 > 解决方案 > SharpZipLib 在提交更新时抛出 System.IO.FileNotFoundException

问题描述

当我AddAndUpdate()在循环中运行时,我会收到此错误,但并非总是如此,因此有时它也可以工作,并且使用相同的数据。

我试着放Task.Delay,但这也不起作用。我认为有时可能与磁盘写入有关。有谁知道它可以是什么?

ZipFile处置时关闭,CompressionProvider但这不会在循环中发生。

protected void CreateIfNull()
{
    if (_zipFile != null) return;
    _zipFile = ZipFile.Create(_filePath);
}


private async Task AddAndUpdateAsync(string containerName, string blobName, string prefix)
{
    if (!await _storage.BlobExistsAsync(containerName, blobName))
    {
        return;
    }

    using (var stream = await _storage.GetBlobStreamAsync(containerName, blobName))
    {
    string fileName = Path.Combine(prefix, containerName, blobName);
        AddAndUpdate(stream, fileName);
    }
}

public void AddAndUpdate(string containerName, string blobName, string prefix = "")
{
    try
    {
        Monitor.Enter(_lockObject);
        Microsoft.Threading.AsyncPump.Run(async delegate
        {
            await AddAndUpdateAsync(containerName, blobName, prefix);
        });
    }
    catch(Exception ex)
    {
        Console.WriteLine(ex);
        throw;
    }
    finally
    {
        Monitor.Exit(_lockObject);
    }
}

public void AddAndUpdate(Stream stream, string filePath)
{
    if (stream == null || stream.Length == 0) return;

    CreateIfNull();
    _zipFile.BeginUpdate();
    _zipFile.Add(new CustomStaticDataSource(stream), ZipEntry.CleanName(filePath));
    _zipFile.CommitUpdate();
}

这是跟踪:

Test Name:    TestExport
Test FullName:    Company.App.UnitTest.ExportTest.TestExport
Test Source:  C:\Projects\Visual Studio\Templex\Company.AppUnitTest\ExportTest.cs : line 45
Test Outcome: Failed
Test Duration:    0:00:08,2825027

Result StackTrace:    
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
   at System.IO.File.InternalMove(String sourceFileName, String destFileName, Boolean checkHost)
   at ICSharpCode.SharpZipLib.Zip.DiskArchiveStorage.ConvertTemporaryToFinal()
   at ICSharpCode.SharpZipLib.Zip.ZipFile.RunUpdates()
   at ICSharpCode.SharpZipLib.Zip.ZipFile.CommitUpdate()
   at Company.Compression.CompressionProvider.AddAndUpdate(Stream stream, String filePath) in C:\Projects\Visual Studio\Templex\Company.Compression\CompressionProvider.cs:line 77
   at Company.Compression.CompressionProvider.<AddAndUpdateAsync>d__8.MoveNext() in C:\Projects\Visual Studio\Templex\Company.Compression\CompressionProvider.cs:line 45
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
   at Company.Compression.CompressionProvider.<>c__DisplayClass9_0.<<AddAndUpdate>b__0>d.MoveNext() in C:\Projects\Visual Studio\Templex\Company.Compression\CompressionProvider.cs:line 56
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
   at Microsoft.Threading.AsyncPump.Run(Func`1 func) in C:\Projects\Visual Studio\Templex\Company.Utilities\AsyncPump.cs:line 32
   at Company.Compression.CompressionProvider.AddAndUpdate(String containerName, String blobName, String prefix) in C:\Projects\Visual Studio\Templex\Company.Compression\CompressionProvider.cs:line 62
   at Company.App.UnitTest.ExportTest.<TestExport>d__2.MoveNext() in C:\Projects\Visual Studio\Templex\Company.AppUnitTest\ExportTest.cs:line 65
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.ThreadOperations.ExecuteWithAbortSafety(Action action)
Result Message:   
Test method Company.App.UnitTest.ExportTest.TestExport threw exception: 
System.IO.FileNotFoundException: Could not find file 'C:\Projects\Visual Studio\Templex\Company.AppUnitTest\TestData\export.zip.361.tmp'.
Result StandardOutput:    
System.IO.FileNotFoundException: Could not find file 'C:\Projects\Visual Studio\Templex\Company.AppUnitTest\TestData\export.zip.361.tmp'.
File name: 'C:\Projects\Visual Studio\Templex\Company.AppUnitTest\TestData\export.zip.361.tmp'
   at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
   at System.IO.File.InternalMove(String sourceFileName, String destFileName, Boolean checkHost)
   at ICSharpCode.SharpZipLib.Zip.DiskArchiveStorage.ConvertTemporaryToFinal()
   at ICSharpCode.SharpZipLib.Zip.ZipFile.RunUpdates()
   at ICSharpCode.SharpZipLib.Zip.ZipFile.CommitUpdate()
   at Company.Compression.CompressionProvider.AddAndUpdate(Stream stream, String filePath) in C:\Projects\Visual Studio\Templex\Company.Compression\CompressionProvider.cs:line 77
   at Company.Compression.CompressionProvider.<AddAndUpdateAsync>d__8.MoveNext() in C:\Projects\Visual Studio\Templex\Company.Compression\CompressionProvider.cs:line 45
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
   at Company.Compression.CompressionProvider.<>c__DisplayClass9_0.<<AddAndUpdate>b__0>d.MoveNext() in C:\Projects\Visual Studio\Templex\Company.Compression\CompressionProvider.cs:line 56
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
   at Microsoft.Threading.AsyncPump.Run(Func`1 func) in C:\Projects\Visual Studio\Templex\Company.Utilities\AsyncPump.cs:line 32
   at Company.Compression.CompressionProvider.AddAndUpdate(String containerName, String blobName, String prefix) in C:\Projects\Visual Studio\Templex\Company.Compression\CompressionProvider.cs:line 54

标签: c#.netzip

解决方案


当存储提供程序是 LocalStorage 时,GetBlobStreamAsync 和 BlobExistsAsync 似乎不是线程安全的。


推荐阅读