Mono中的C#FileStream - 文件共享冲突

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Mono中的C#FileStream - 文件共享冲突相关的知识,希望对你有一定的参考价值。

我有一个使用Mono在Raspbian上运行的C#WinForms应用程序。它有一个计时器。当OnTimedEvent触发时,我检查是否对我要上传的文件具有独占访问权限(以确保它已完成写入磁盘),然后尝试上传。如果上传成功,我将文件移动到存档文件夹,否则我将其留在那里并等待下一个计时器事件。连接到Internet时没有问题,但是当我测试没有并且我的上传失败时,第二个OnTimedEvent在检查同一文件是否准备就绪时会再次出现异常。我正进入(状态 :

Error message: ***Sharing violation on path 'path'
***HResult: ***-2147024864

检查文件是否准备好的方法:

 public static bool IsFileReady(string filename)
    {

        // If the file can be opened for exclusive access it means that the file
        // is no longer locked by another process.
        try
        {
            var inputStream = File.Open(filename, FileMode.Open, FileAccess.Read, FileShare.None);

            bool test = inputStream.Length > 0;

            inputStream.Close();
            inputStream.Dispose();

            return test;
        }
        catch (Exception e)
        {
            //log
            throw e;
        }
    }

这是在OntimedEvent上执行的:

            var csvFiles = from f in di.GetFiles()
                        where f.Extension == ".csv"
                        select f;  //get csv files in upload folder

            foreach (var file in csvFiles)
            {
                if (IsFileReady(file.FullName))  //check that file is done writing before trying to move.
                {
                    bool IsUploadSuccess = await WritingCSVFileToS3Async(file);//.Wait();  //upload file to S3

                    if (IsUploadSuccess)
                    {
                        File.Move(file.FullName, archivePath + file.Name);  //move to completed folder if upload successful. else, leave there for next upload attempt
                    }
                }
            }

根据我的理解,看起来我的第一个FileStream(File.Open)在第二个事件触发时仍然锁定了文件。但是,我已经将.Close()和.Dispose()添加到IsFileReady方法,但这似乎不起作用。

任何帮助,将不胜感激!

编辑:下面是WritingCSVFileToS3Async方法。

static async Task<bool> WritingCSVFileToS3Async(FileInfo file)
    {
        try
        {
            client = new AmazonS3Client(bucketRegion);

            // Put the object-set ContentType and add metadata.
            var putRequest = new PutObjectRequest
            {
                BucketName = bucketName,
                Key = file.Name,
                FilePath = file.FullName ,
                ContentType = "text/csv"
            };
            //putRequest.Metadata.Add("x-amz-meta-title", "someTitle"); //don't need meta data at this time

            PutObjectResponse response = await client.PutObjectAsync(putRequest);

            if (response.HttpStatusCode == System.Net.HttpStatusCode.OK)
                return true;
            else
                return false;
        }
        catch (AmazonS3Exception e)
        {
            ErrorLogging.LogErrorToFile(e);
            return false;
        }
        catch (Exception e)
        {
            ErrorLogging.LogErrorToFile(e);
            return false;
        }

此外,我在Windows上运行相同的应用程序,并得到一个类似的例外:

The process cannot access the file 'path' because it is being used by another process.
答案

我相信我发现了这个问题。我注意到我没有捕获PUT请求的客户端超时异常(未连接到Internet)。我的计时器间隔是20秒,比S3客户端超时(30秒)短。因此,在第二个计时器事件触发时,客户端仍然将文件绑定,因此访问冲突。我将定时器间隔增加到60秒,现在我捕获客户端超时异常,并可以在下一个定时器事件之前处理它。

谢谢你的帮助。

以上是关于Mono中的C#FileStream - 文件共享冲突的主要内容,如果未能解决你的问题,请参考以下文章

C# 中的 FileStream 和 FileSystemWatcher,奇怪的问题“进程无法访问文件”

C#中的IO流操作(FileStream)

Mono(Linux,C#):无法找到同一文件夹中的DLL(System.DllNotFoundException)

File.Copy 与手动 FileStream.Write 用于复制文件

47.C#--使用FileStream文件流来实现多媒体文件的复制

sql server2008中的FILESTREAM