“进程无法访问该文件,因为它正被另一个进程使用”与图像

时间:2021-02-11 21:04:32

I've seen many issues like this that have been solved and the problem was mostly due to streams not being disposed of properly.

我已经看到很多这样的问题已经解决了,问题主要是由于流没有被妥善处理。

My issue is slightly different, here follow a code snippet

我的问题略有不同,请按照代码段进行操作

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

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

Where Images is a custom struct and item.File is the raw data, byte[].

其中Images是自定义结构和item.File是原始数据byte []。

My issue is that at the line where the WriteAllBytes is called, an exception is thrown. The message reads:

我的问题是,在调用WriteAllBytes的行中,抛出异常。消息如下:

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

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

Again I have no clue how am I going to somehow close the process.

我再也不知道如何以某种方式关闭这个过程。

7 个解决方案

#1


18  

Since File.Create returns the stream i would dispose it properly:

由于File.Create返回流,我会正确处理它:

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

or you can use the stream to write to the file directly:

或者您可以使用流直接写入文件:

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

or, probably the easiest, use File.WriteAllBytes alone:

或者,可能是最简单的,单独使用File.WriteAllBytes:

File.WriteAllBytes(newPath, item.File);

Creates a new file, writes the specified byte array to the file, and then closes the file. If the target file already exists, it is overwritten.

创建一个新文件,将指定的字节数组写入该文件,然后关闭该文件。如果目标文件已存在,则会被覆盖。

#2


4  

You state that your problem has nothing to do with disposing streams but check this MSDN article:

您声明您的问题与处理流无关,但请查看此MSDN文章:

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

What does File.Create return? A FileStream!!!!

File.Create返回什么?一个FileStream !!!!

And, at the end of the day, why are you using File.Create if File.WriteAllBytes creates a file if this doesn't exist? ;)

并且,在一天结束时,如果File.WriteAllBytes创建一个文件,如果不存在,为什么还要使用File.Create? ;)

Creates a new file, writes the specified byte array to the file, and then closes the file. If the target file already exists, it is overwritten.

创建一个新文件,将指定的字节数组写入该文件,然后关闭该文件。如果目标文件已存在,则会被覆盖。

Check it on MSDN too: http://msdn.microsoft.com/en-us/library/system.io.file.writeallbytes.aspx

也可以在MSDN上查看它:http://msdn.microsoft.com/en-us/library/system.io.file.writeallbytes.aspx

#3


1  

using (FileStream fs = 
new FileStream(filePath,
    FileMode.Open, FileAccess.Read, FileShare.ReadWrite))

Your log may be write locked, so try with FileShare.ReadWrite.

您的日志可能被写入锁定,因此请尝试使用FileShare.ReadWrite。

#4


1  

The create method opens the file for writing and returns a FileStream object for you to work with. Just because you are not referencing it does not mean it does not need to be returned.

create方法打开要写入的文件,并返回一个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);
                }

#5


0  

The File.WriteAllBytes creates the file if necessary. You can juts use:

如有必要,File.WriteAllBytes将创建该文件。你可以使用juts:

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

And are you combine path correctly?

你正确地组合路径吗?

#6


0  

This is the most specific way to accomplish what you are trying to do:

这是完成您要执行的操作的最具体方法:

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

You also need to fix your logic for creating the path, which I have done in my example above. You were concatenating the newPath over and over again.

您还需要修复用于创建路径的逻辑,这是我在上面的示例中所做的。你一遍又一遍地连接newPath。

#7


-1  

Force the garbage collector to clean.

强制垃圾收集器清理。

GC.Collect();

#1


18  

Since File.Create returns the stream i would dispose it properly:

由于File.Create返回流,我会正确处理它:

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

or you can use the stream to write to the file directly:

或者您可以使用流直接写入文件:

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

or, probably the easiest, use File.WriteAllBytes alone:

或者,可能是最简单的,单独使用File.WriteAllBytes:

File.WriteAllBytes(newPath, item.File);

Creates a new file, writes the specified byte array to the file, and then closes the file. If the target file already exists, it is overwritten.

创建一个新文件,将指定的字节数组写入该文件,然后关闭该文件。如果目标文件已存在,则会被覆盖。

#2


4  

You state that your problem has nothing to do with disposing streams but check this MSDN article:

您声明您的问题与处理流无关,但请查看此MSDN文章:

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

What does File.Create return? A FileStream!!!!

File.Create返回什么?一个FileStream !!!!

And, at the end of the day, why are you using File.Create if File.WriteAllBytes creates a file if this doesn't exist? ;)

并且,在一天结束时,如果File.WriteAllBytes创建一个文件,如果不存在,为什么还要使用File.Create? ;)

Creates a new file, writes the specified byte array to the file, and then closes the file. If the target file already exists, it is overwritten.

创建一个新文件,将指定的字节数组写入该文件,然后关闭该文件。如果目标文件已存在,则会被覆盖。

Check it on MSDN too: http://msdn.microsoft.com/en-us/library/system.io.file.writeallbytes.aspx

也可以在MSDN上查看它:http://msdn.microsoft.com/en-us/library/system.io.file.writeallbytes.aspx

#3


1  

using (FileStream fs = 
new FileStream(filePath,
    FileMode.Open, FileAccess.Read, FileShare.ReadWrite))

Your log may be write locked, so try with FileShare.ReadWrite.

您的日志可能被写入锁定,因此请尝试使用FileShare.ReadWrite。

#4


1  

The create method opens the file for writing and returns a FileStream object for you to work with. Just because you are not referencing it does not mean it does not need to be returned.

create方法打开要写入的文件,并返回一个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);
                }

#5


0  

The File.WriteAllBytes creates the file if necessary. You can juts use:

如有必要,File.WriteAllBytes将创建该文件。你可以使用juts:

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

And are you combine path correctly?

你正确地组合路径吗?

#6


0  

This is the most specific way to accomplish what you are trying to do:

这是完成您要执行的操作的最具体方法:

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

You also need to fix your logic for creating the path, which I have done in my example above. You were concatenating the newPath over and over again.

您还需要修复用于创建路径的逻辑,这是我在上面的示例中所做的。你一遍又一遍地连接newPath。

#7


-1  

Force the garbage collector to clean.

强制垃圾收集器清理。

GC.Collect();