由于另一个进程正在使用该文件,所以该进程无法访问该文件。

16

我从SQL Server数据库字段中获取二进制数据,并在应用程序具有权限的目录中创建一个文档。然而,我仍然遇到了标题中指定的错误。我尝试了网上提供的许多建议,包括之前在Stackoverflow上建议的方案。我还使用了ProcessExplorer>查找句柄来定位锁定,但它没有返回任何东西,好像文件没有被锁定。

我正在使用以下代码将文件保存到文件系统中,然后我尝试在应用程序过程的另一个方法中复制此文件到新位置。正是这个复制方法,它需要新创建的文件的路径,才会抛出异常。

文件本身已经带有其内容,我可以通过Windows Explorer打开它而没有任何问题。

我是否漏掉了一些非常明显的东西?我是否正确地从数据库中创建了文件?任何有关解决或更好地诊断问题的帮助都将不胜感激。

// Get file from DB
FileStream fs = new FileStream(
    "C:\myTempDirectory\myFile.doc", FileMode.OpenOrCreate, FileAccess.Write);
BinaryWriter br = new BinaryWriter(fs);
br.Write("BinaryDataFromDB");
fs.Flush();
fs.Close();
fs.Dispose();

// Copy file
File.Copy(sourceFileName, destinationFilename, true);

你能发布实际的代码吗?看起来有一个未知的问题,可能隐藏在其他地方... - Bloodyaugust
我知道你可能只是为了提问而进行了文本替换,但是由于反斜杠转义的原因,你的文件路径应该是 @"C:\myTempDirectory\myFile.doc" - Jacob
你确定异常并不是指目标文件名正在被另一个进程使用吗? - Jacob
非常感谢各位的帮助。看起来存在一个更深层次的问题,暂时通过手动调用垃圾回收(这是错误的!!并将在明天处理!)解决。代码太庞大无法上传,因此只能提供精简版本。再次感谢您的帮助,非常感激。 - Cragly
9个回答

28

在你处理完流之后,尝试添加一个调用GC.Collect()的语句来强制垃圾回收器清理内存。

// Get file from DB 
using(FileStream fs = new FileStream("C:\myTempDirectory\myFile.doc", FileMode.OpenOrCreate, FileAccess.Write)) 
using(BinaryWriter br = new BinaryWriter(fs))
{
   br.Write("BinaryDataFromDB"); 
   fs.Flush(); 
}

//Force clean up
GC.Collect();

// Copy file 
File.Copy(sourceFileName, destinationFilename, true); 

非常感谢,看起来已经解决了。然而,即使我调用了close(),它仍然保留着某些错误的东西。好吧,至少我可以进入下一个阶段了。非常感谢所有帮助我找到问题根源的人,非常感激。今晚我会睡得很香 :) - Cragly
12
为什么在Dispose()中流不会立即关闭? - Kugel
5
GC.Collect() => 这太邪恶了! - user384080
1
我认为GC.Collect()是有害的,应该被移除。此外,在fs.Flush()之后应该加上fs.Close();。 - Ajit Goel
@AjitGoel 使用using块调用FileStream的Dispose方法,而Dispose方法又调用Close()方法。我认为问题在于这只是将对象“标记”为垃圾回收,有可能在最后一行之前尚未完成。调用GC.Collect()会强制进行垃圾回收。这不是建议,而是问题的解释。 - Jesper Palm
1
为什么需要 GC.Collect();?我觉得这没有意义。Dispose 应该足够了。 - Sriram Sakthivel

4
将您的代码更改如下,问题在于当您需要时,文件流未被垃圾回收:
    // Get file from DB 
using (FileStream fs = new FileStream("C:\myTempDirectory\myFile.doc", FileMode.OpenOrCreate, FileAccess.Write)) 
{
    BinaryWriter br = new BinaryWriter(fs); 
    br.Write("BinaryDataFromDB"); 
    fs.Flush(); 
    fs.Close(); 
}

// Copy file 
File.Copy(sourceFileName, destinationFilename, true);

很遗憾,没有成功!这应该是一件非常简单的事情。再次感谢大家的努力,非常感激。 - Cragly

3

我明白了,虽然错误调试器说错误在这段代码里,但实际上并不是那里出了问题。

我曾遇到类似的问题,找到了以下解决方案,请大家参考以上所有帖子,希望能对你有所帮助。


我使用了图片,并通过从数据库中检索并保存为"temp.bmp"的正常编码方式将其显示在picturebox中,没有使用"using"关键字。首先使用以下代码:

PictureBox1.Image = Image.FromFile("temp.bmp");

出现错误时我一头雾水,不知所措。于是我想出了以下解决方案:


不要直接进行赋值,试试这段代码:

Bitmap img;
using (Bitmap bmp = new Bitmap("temp.bmp"))
{
    img = new Bitmap(bmp);
}
pictureBox1.Image = img;

到了文件流部分,我只是使用了以下普通代码:

FileStream fs = new FileStream("filepath",FileMode.Create);

它像小菜一样轻松地工作了


它真的很有帮助


谢谢Murali。我可以看到通过将值分配给一个新对象,然后将该对象的值分配给不属于using语句的部分,这种方法是可行的。感谢您的更新,希望对其他遇到同样问题的人有所帮助。 - Cragly

3

那么using呢?

string source = @"C:\myTempDirectory\myFile.doc";
using(FileStream fs = new FileStream(
    source, FileMode.OpenOrCreate, FileAccess.Write, FileShare.Read))
{
    BinaryWriter br = new BinaryWriter(fs);
    br.Write("BinaryDataFromDB");
}

File.Copy(sourceFileName, destinationFilename, true);

编辑:尝试通知一个FileShare.Read权限。


那么在 BinaryWriter 上使用怎么样? - Jesper Palm
很遗憾,它没有起作用。甚至尝试过在FileStream和BinaryWriter上使用Close()和不使用Close()。 - Cragly
1
添加 FileShare.Read 似乎 已经为我解决了这个问题。 - Rowland Shaw

1

是否有后台进程(如防病毒软件或文件系统索引)锁定了文件,导致您的应用程序出现问题?尝试暂停3秒钟,看看是否可以解决您的问题。

using System.Threading;

fs.Dispose();
Thread.Sleep(3000);
// Copy file

1

是这样的,Filestream和BinaryWriter不能同时使用吗?例如,一个streamwriter和一个streamreader不能同时在同一个文件上调用。但是,就我所知,这没有意义,应该不是这种情况。也许尝试同时关闭BR?


1
尝试在复制之前处理您的BinaryWriter对象。

没办法,伙计们。我对 BinaryWriter 执行了 Flush() 和 Close() 操作,仍然收到相同的错误。 - Cragly

0

这是我所做的:

Stream stream = new MemoryStream();
var tempStream = new FileStream(pathToFile, FileMode.Open);
tempStream.CopyTo(stream);
tempStream.Close();

然后在需要的地方使用stream对象。


-1

我似乎只在发布应用程序后遇到这个问题。如果你关闭消息框并尝试再次调试,什么也不会发生。 MS帮助说要完全退出Visual Studio并重新启动它。更容易的方法是打开任务管理器并结束进程。它的名称将是解决方案名称后跟“.vshost”(例如,项目名称:PLC.sln;进程名称:PLC.vshost.exe)。该进程将自动重启。在Windows 7中,结束进程时通常会看到一些变化。但在10中,任务管理器窗口很少改变。 当我尝试在更改代码后测试程序时,我会收到此消息。显然,在停止调试时未关闭.exe文件,当VS尝试编写新编译的exe文件时出现错误。有时我必须两次结束进程才能防止错误消息再次出现。(我必须遇到两次错误;两次结束进程然后重新运行没有帮助。) 这是Visual Studio中的一个错误。


请尝试对您的答案进行格式化。这样一个大段文本很难阅读。 - martianwars

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接