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

时间:2019-10-02 20:23:15

标签: c# azure azure-blob-storage

我已经开发了一个简单的应用程序,只需要将文件从文件夹上传到Azure Blob存储,从VS运行时我运行得很好,但是在发布的应用程序中,偶尔会出现此错误:< / p>

  

ved System.IO .__ Error.WinIOError(Int32 errorCode,String,   也许FullPath)ved System.IO.FileStream.Init(字符串路径,FileMode   模式,FileAccess访问权限,Int32权限,布尔useRights,FileShare   份额,Int32 bufferSize,FileOptions选项,SECURITY_ATTRIBUTES   secAttrs,字符串msgPath,布尔bFromProxy,布尔useLongPath,   Boolean checkHost)ved System.IO.FileStream..ctor(字符串路径,   FileMode模式,FileAccess访问)   Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob.UploadFromFile(String   路径,FileMode模式,AccessCondition accessCondition,   BlobRequestOptions选项,OperationsContext operationContext)ved   Program.MainWindow.Process(对象发送者,   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);
        }
    }
}

捕获中的IOException有时会被击中,您知道如何解决此问题吗?

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

https://docs.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_

2 个答案:

答案 0 :(得分:1)

  

我观察到错误仅在将文件复制到受监视的文件夹时发生,如果我将其拖动,是否可以正常工作?

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

尝试从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()调用之间被另一个进程再次锁定。

答案 1 :(得分:-1)

这通常是由于DotNet所引用的某些文件丢失而引起的。我遇到了这个错误,当我深入研究时,我知道class SqliteEngine: def __init__(self): self._conn_engine = create_engine("sqlite://") self._conn_engine.execute("pragma foreign_keys=ON") def get_engine(self): return self._conn_engine def get_session(self): Session = sessionmaker(bind=self._conn_engine, autoflush=True) return Session() @pytest.fixture(scope="session") def sqlite_engine(): sqlite_engine = SqliteEngine() return sqlite_engine 丢失了。 snippet中的一段代码显示了文件的重要性。

它是指实际的源文件,因此必须存在。当该源不可用或其他位置不可用时,该页面的代码段引用将失败,并且您会收到该错误(这也是为什么它引用.cs文件的原因)。

如果这不是相同的问题,则可能是由于缺少其他文件引起的。因此,请尝试重新安装并重新编译它。