c# - 在已发布的应用程序中上传到 Blob 存储时出现 IOException

标签 c# azure azure-blob-storage

我开发了一个简单的应用程序,只需将文件从文件夹上传到Azure Blob存储,当我从VS运行时运行良好,但在发布的应用程序中我偶尔会收到此错误:

ved System.IO.__Error.WinIOError(Int32 errorCode, String, maybeFullPath) ved System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost) ved System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access) ved Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob.UploadFromFile(String path, FileMode mode, AccessCondition accessCondition, BlobRequestOptions options, OperationsContext operationContext) ved Program.MainWindow.Process(object sender, NotifyCollectionChangedEventArgs e)

我的上传代码如下所示:

private void Process(object sender, NotifyCollectionChangedEventArgs e)
{
    if (paths.Count > 0){
        var currentPath = paths.Dequeue();
        CloudStorageAccount storageAccount = CloudStorageAccount.Parse(UserSettings.Instance.getConnectionString());
        CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
        CloudBlobContainer blobContainer = blobClient.GetContainerReference(UserSettings.Instance.getContainer());
        CloudBlockBlob b = blobContainer.GetBlockBlobReference(System.IO.Path.GetFileName(currentPath));
        try
        {
           b.UploadFromFile(currentPath, FileMode.Open);
        }
        catch (StorageException s)
        {
            throw new System.InvalidOperationException("Could not connect to the specified storage account. Please check the configuration.");
        }
        catch (IOException exc)
        {
            throw new System.InvalidOperationException(exc.StackTrace);
        }
    }
}

catch 中的 IOException 偶尔会遇到,知道如何解决这个问题吗?

如果我浏览文档,我只会收到通知,如果发生存储服务错误,就会发生异常。知道如何进一步调查吗?

https://learn.microsoft.com/en-us/java/api/com.microsoft.azure.storage.blob._cloud_blob.uploadfromfile?view=azure-java-legacy#com_microsoft_azure_storage_blob__cloud_blob_uploadFromFile_final_String_

最佳答案

I observed that the error only occours when i copy the files into the monitored folder, if I drag them, it works just fine?

您的应用程序似乎正在尝试读取仍在写入磁盘(不完整)或被其他进程锁定的本地文件。拖动文件在某种程度上是“原子”操作(即非常快),因此大大减少了出现此错误的机会。

尝试实现 this answer 中的方法测试在调用 UploadFromFile() 之前文件是否未锁定。现在,根据您的代码逻辑,如果文件被锁定,您将需要实现某种形式的“重试”。这是一个例子:

    protected virtual bool IsFileLocked(FileInfo file)
    {
        FileStream stream = null;

        try
        {
            stream = file.Open(FileMode.Open, FileAccess.Read, FileShare.None);
        }
        catch (IOException)
        {
            //the file is unavailable because it is:
            //still being written to
            //or being processed by another thread
            //or does not exist (has already been processed)
            return true;
        }
        finally
        {
            if (stream != null)
                stream.Close();
        }

        //file is not locked
        return false;
    }

    private void Process(object sender, NotifyCollectionChangedEventArgs e)
    {
        if (paths.Count > 0)
        {
            var currentPath = paths.Dequeue();
            CloudStorageAccount storageAccount = CloudStorageAccount.Parse(UserSettings.Instance.getConnectionString());
            CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
            CloudBlobContainer blobContainer = blobClient.GetContainerReference(UserSettings.Instance.getContainer());
            CloudBlockBlob b = blobContainer.GetBlockBlobReference(System.IO.Path.GetFileName(currentPath));
            try
            {
                FileInfo fi = new FileInfo(currentPath);
                while (IsFileLocked(fi))
                    Thread.Sleep(5000); // Wait 5 seconds before checking again
                b.UploadFromFile(currentPath, FileMode.Open);
            }
            catch (StorageException s)
            {
                throw new System.InvalidOperationException("Could not connect to the specified storage account. Please check the configuration.");
            }
            catch (IOException exc)
            {
                throw new System.InvalidOperationException(exc.StackTrace);
            }
        }
    }

请注意,这绝不能保证文件不会在 IsFileLocked() 调用和 b.UploadFromFile() 调用之间再次被另一个进程锁定.

关于c# - 在已发布的应用程序中上传到 Blob 存储时出现 IOException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58208882/

相关文章:

azure - 如何从网络角色引用关联的存储帐户?

c# - 使用属性丰富 Seq 日志语句,而无需将它们包含在消息行中(使用 Serilog)

c# - MEF 从网络共享文件夹加载插件

c# - WPF设计;一个窗口中的多个 View

c# - 由缓慢的客户端引起的 BadHttpRequestException 出现在我的应用程序见解中

azure - 设置速度极慢 :upgrade on magento 2. 4

azure - 我收到模拟和真实 Azure 存储的错误请求 (400) 消息

c# - 如何设置列长度和类型

azure - 如何获取触发Azure数据工厂管道的文件的名称?

azure - 删除 Blob 存储中具有名称的所有内容