web-dev-qa-db-ja.com

「別のプロセスによって使用されているため、プロセスはファイルにアクセスできません」と画像

私はこのような解決された多くの問題を見てきました、そして問題は主にストリームが適切に処分されなかったことが原因でした。

私の問題は少し異なります。ここではコードスニペットに従います

 foreach (Images item in ListOfImages)
 {
      newPath = Path.Combine(newPath, item.ImageName + item.ImageExtension);
      File.Create(newPath);

      File.WriteAllBytes(newPath, item.File);
 }

ここで、Imagesはカスタム構造体であり、item.Fileは生データ、byte []です。

私の問題は、WriteAllBytesが呼び出された行で、例外がスローされることです。メッセージは次のとおりです。

The process cannot access the file because it is being used by another process

繰り返しますが、どういうわけかプロセスをcloseする方法がわかりません。

9
Scriptworks

File.Createは、適切に処理するストリームを返します。

using(var stream = File.Create(newPath)){}
File.WriteAllBytes(newPath, item.File);

または、ストリームを使用してファイルに直接書き込むことができます。

using (FileStream fs = File.Create(newPath))
{
    fs.Write(item.File, 0, item.File.Length);
}

または、おそらく最も簡単な方法として、 File.WriteAllBytes 単独:

File.WriteAllBytes(newPath, item.File);

新しいファイルを作成し、指定されたバイト配列をファイルに書き込んでから、ファイルを閉じます。ターゲットファイルがすでに存在する場合は、上書きされます。

21
Tim Schmelter

あなたはあなたの問題がストリームの破棄とは何の関係もないと述べていますが、このMSDNの記事をチェックしてください:

http://msdn.Microsoft.com/en-us/library/d62kzs03.aspx

File.Createは何を返しますか? FileStream !!!!

そして、結局のところ、File.Createがファイルを作成するのに、これが存在しないのにFile.WriteAllBytesを使用しているのはなぜですか? ;)

新しいファイルを作成し、指定されたバイト配列をファイルに書き込んでから、ファイルを閉じます。ターゲットファイルがすでに存在する場合は、上書きされます。

MSDNでも確認してください: http://msdn.Microsoft.com/en-us/library/system.io.file.writeallbytes.aspx

4

create method は、書き込み用にファイルを開き、操作するFileStreamオブジェクトを返します。あなたがそれを参照していないという理由だけではそれを返す必要がないことを意味しません

foreach (Images item in ListOfImages)
                {
                    newPath = Path.Combine(newPath, item.ImageName + item.ImageExtension);
                    FileStream f = File.Create(newPath);

                    f.Write(item.File, 0, item.File.Length);
                }
using (FileStream fs = 
new FileStream(filePath,
    FileMode.Open, FileAccess.Read, FileShare.ReadWrite))

ログが書き込みロックされている可能性があるため、FileShare.ReadWriteを試してください。

1
Ashwin Patil

これは、あなたがやろうとしていることを達成するための最も具体的な方法です。

foreach (Images item in ListOfImages)
{
    using (System.IO.FileStream output = new System.IO.FileStream(Path.Combine(newPath, item.ImageName + item.ImageExtension),
        System.IO.FileMode.Create, System.IO.FileAccess.Write))
    {
        output.Write(item.File, 0, item.File.Length);
        output.Flush();
        output.Close();
    }
}

また、上記の例で行った、パスを作成するためのロジックを修正する必要があります。 newPathを何度も連結していました。

0

File.WriteAllBytes必要に応じてファイルを作成します。あなたは使用することができます:

foreach (Images item in ListOfImages)
{
    newPath = Path.Combine(newPath, item.ImageName + item.ImageExtension);
    File.WriteAllBytes(newPath, item.File);
}

そして、パスを正しく組み合わせていますか?

0
Hamlet Hakobyan