【问题标题】:How to avoid exception The process cannot access the file because it is being used by another process. in .net如何避免异常该进程无法访问该文件,因为它正在被另一个进程使用。在.net
【发布时间】:2017-04-06 20:26:45
【问题描述】:

我正在使用以下代码解压缩 a.gz 文件。由于我有大量文件,我正在使用 TPL 任务来运行此代码。但我曾经得到.NET 异常:

该进程无法访问该文件,因为它正被另一个进程使用。

如何解决这个问题?
使用的代码如下:

private static void Decompress(FileInfo fileToDecompress)
{
    using (FileStream originalFileStream = fileToDecompress.OpenRead())
    {
        string currentFileName = fileToDecompress.FullName;
        string newFileName = currentFileName.Remove(currentFileName.Length - 
                                          fileToDecompress.Extension.Length);
        using (FileStream decompressedFileStream = File.Create(newFileName))
        {
            using (GZipStream decompressionStream = 
                     new GZipStream(originalFileStream, 
                                    CompressionMode.Decompress))
            {
                decompressionStream.CopyTo(decompressedFileStream);
            }
        }
    }
    //File.Move(myffile, Path.ChangeExtension(myffile, ".jpg"));
}

调用代码如下图

var list = ftp.GetFileList(remotepath);

//-------------------
DateTime dt = DateTime.Now;
string st = String.Format("{0:yyyyMMdd}", dt);//20161120
Task[] myTasks = new Task[list.Count];
int i = 0;
foreach (string item in list)
{
     if (item.StartsWith("GExport_") && (!item.ToUpper().Contains("DUM")) && (item.Contains(st)) && (!item.ToUpper().Contains("BLK")))
     {
         4gpath = item;
        //Downloadfile()   
        ftp.Get(dtr["REMOTE_FILE_PATH"].ToString() + 4gpath , @localDestnDir + "\\" + dtr["SOURCE_PATH"].ToString());
        download_location_hw = dtr["LOCAL_FILE_PATH"].ToString();
        // Spin off a background task to process the file we just downloaded
        myTasks[i++] = Task.Factory.StartNew(() =>
        {
            //Extractfile()             
            ExtractZipfiles(download_location_hw + "//" + huwawei4gpath, dtr["REMOTE_FILE_PATH"].ToString(), 
             dtr["FTP_SERVER"].ToString(), dtr["FTP_USER_ID"].ToString(),
             dtr["TECH_CODE"].ToString(), dtr["VENDOR_CODE"].ToString());
        }
    }
}

private static void ExtractZipfiles(string download_location_hw,string remotepath,string server,string userid,string tech,string vendor)
{
    if (download_location_hw.Contains(".gz"))
    {
        DirectoryInfo directorySelected = new DirectoryInfo(Path.GetDirectoryName(download_location_hw));
        foreach (FileInfo fileToDecompress in directorySelected.GetFiles("*.gz"))
        {
            Decompress(fileToDecompress);
        }
    }

}

【问题讨论】:

  • 你能显示调用这个方法的代码吗?特别是 TPL
  • 我发布了调用代码
  • myTasks有什么用?
  • 以更快的方式下载和解压大量文件

标签: c# .net file exception task-parallel-library


【解决方案1】:

您可能正在将您的任务下载的zip 文件提取到同一文件夹中:

download_location_hw = dtr["LOCAL_FILE_PATH"].ToString();
var directorySelected = new DirectoryInfo(Path.GetDirectoryName(download_location_hw));

如果出于某种原因您有两个文件被定位到相同的本地路径,最终的foreach 语句将与其他任务有交集:

foreach (var fileToDecompress in directorySelected.GetFiles("*.gz"))
{
    Decompress(fileToDecompress);
}

在这里,您正在搜索文件夹中的所有*.gz 文件,即使是那些仍处于下载模式或正在被其他进程解压缩的文件。所以你应该确定每个任务都在不同的文件夹中运行。

如果你想简单地修正你的代码,你可以试试这个(这里的主要变化不是枚举所有存档文件,而是简单地从任务参数中获取一个,FileInfo constructor):

private static void ExtractZipfiles(string download_location_hw,string remotepath,string server,string userid,string tech,string vendor)
{
    if (download_location_hw.Contains(".gz") && File.Exists(download_location_hw))
    {
        Decompress(new FileInfo(download_location_hw));
    }
}

【讨论】:

  • 每个任务对应一个文件?
  • @peter 更新了答案。你不应该一次又一次地问同样的问题
【解决方案2】:

各种任务在同一下载路径上运行并导致冲突。 例如。任务 1 将 a.gz、b.gz 放入,而任务 2 将 c.gz 放入“MyDir”下。

但现在这两个任务都在运行,并在解压缩过程中尝试将文件重命名为 a、b、c。因此,您似乎需要为每个任务创建子目录或为下载的文件名加上唯一标识符的前缀\后缀。

【讨论】:

  • 您正在启动的并行任务正在处理所有文件,而不是仅处理正在下载的文件。
猜你喜欢
  • 1970-01-01
  • 2012-11-29
  • 2010-12-10
相关资源
最近更新 更多