2016-11-23 8 views
1

次のコードを使用してa.gzファイルを解凍しています。膨大な数のファイルがあるので、私はこのコードを実行するためにTPLタスクを使用しています。しかし、私は以前は.NETを取得していました。例外を回避する方法プロセスは別のプロセスによって使用されているため、ファイルにアクセスできません。 in .net

プロセスは別のプロセスで使用されているため、ファイルにアクセスできません。

この問題を解決するにはどうすればよいですか?次のように
コードを使用は、次のとおりです。

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); 
     } 
    } 

} 
+2

このメソッドを呼び出すコードを表示できますか?特に、_TPL_ビット – MickyD

+0

私は呼び出しコード – peter

+0

を投稿しました。 'myTasks'の使い方は? –

答えて

2

以下のようにコードを呼び出す

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")); 
} 

があるあなたは、おそらく同じフォルダにタスク府ダウンロードzipファイルを抽出している:

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

同じ理由で2つのファイルが同じローカルパスをターゲットにしている場合は、最終的にforeachステートメントw病気の他のタスクとの交点を持っている:

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

ここでは、フォルダ内のすべてのファイル*.gz、ダウンロードモードではまだできたとしても、それらのものを探している、または他のプロセスによって減圧されています。したがって、各タスクが別のフォルダで実行されていることを確実に確認する必要があります。

あなたのコードの簡単な補正をしたい場合は、(FileInfo constructorで、すべてのアーカイブファイルを列挙したが、単にタスクの引数から1を取得するためにされていないここでの主な変更)、これを試してください:

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)); 
    } 
} 
+0

これを克服するには、コードスニペットがあります – peter

+0

各タスクは1つのファイルに対応していますか? – VMAtm

+0

@peterが答えを更新しました。 – VMAtm

1

さまざまなタスクが同じダウンロードパス上で動作しており、コリジョンが発生しています。 たとえば、タスク1はa.gz、b.gzを、タスク2はc.gzを "MyDir"に置きます。

ただし、両方のタスクが動作しており、解凍中にファイルの名前をa、b、cに変更しようとしています。したがって、タスクごとにサブディレクトリを作成するか、一意の識別子でダウンロードされたファイル名の接頭辞に接尾辞を付ける必要があるようです。

+0

同じ質問を何度も繰り返すべきではありません。私はあなたを教えてくれませんでした。 – peter

+0

あなたが起動している並列タスクは、ダウンロードしているファイルだけでなくすべてのファイルを処理しています。 – arviman

関連する問題