我想找到一种解决方法,但是我所有的Google搜索都只能通过使用异常处理来创建检查。这与我的宗教信仰背道而驰,所以我想知道是否有人能做得更好?
#1 楼
更新了有关此解决方案的注释:使用FileAccess.ReadWrite
检查只读文件将失败,因此已修改解决方案以使用FileAccess.Read
检查。尽管此解决方案有效,因为如果文件具有写入或读取锁定,尝试使用FileAccess.Read
进行检查将失败,但是,如果文件没有写入或读取锁定,则该解决方案将不起作用。使用FileShare.Read或FileShare.Write访问打开(用于读取或写入)。原始代码:
我过去几年一直使用此代码,但至今没有任何使用出现问题。
了解您对使用异常的犹豫,但是您无法始终避免使用它们:
protected virtual bool IsFileLocked(FileInfo file)
{
try
{
using(FileStream stream = file.Open(FileMode.Open, FileAccess.Read, FileShare.None))
{
stream.Close();
}
}
catch (IOException)
{
//the file is unavailable because it is:
//still being written to
//or being processed by another thread
//or does not exist (has already been processed)
return true;
}
//file is not locked
return false;
}
评论
这是一个很好的解决方案,但是我有一条评论-您可能无法使用访问模式FileAccess.Read打开文件,因为如果文件碰巧是只读的,则ReadWrite总是会失败。
–adeel825
2010-1-29的1:28
-1。这是一个很差的答案,因为在IsFileLocked中关闭文件之后,在线程没有机会打开该文件之前,该文件可能会被另一个线程/进程锁定。
– Polyfun
2010年5月26日15:58
我认为这是一个很好的答案。我将其用作扩展方法ápublic static bool IsLocked(此FileInfo文件){/*...*/}。
– Manzor
2012年7月4日在11:06
@ChrisW:您可能想知道发生了什么。不要惊慌。您只是受到每日WTF社区的愤怒:thedailywtf.com/Comments/…
– Pierre Lebeaupin
2013年3月11日13:15
@ChrisW为什么这是一件坏事。这个社区在这里指出好与坏的答案。如果一堆专业人士注意到这是一件坏事,并且加入downvote,那么该网站就是WAI。在您否定之前,如果您阅读该文章,他们会说“赞成正确答案”而不是反对错误答案。您是否也希望他们在评论中解释他们的投票。感谢您向我介绍另一个好网站!
–Lee Louviere
13年11月11日在15:12
#2 楼
您可能因此而遭受线程争用的情况,有记录在此的示例被用作安全漏洞。如果您检查文件是否可用,然后尝试使用它,则可能会抛出该文件,恶意用户可能会在文件中强加并利用它。最好的选择是尝试catch /最终尝试获取文件句柄。
try
{
using (Stream stream = new FileStream("MyFilename.txt", FileMode.Open))
{
// File/Stream manipulating code here
}
} catch {
//check here why it failed and ask user to retry if the file is in use.
}
评论
+1。没有100%安全的方法来“了解文件是否正在使用中”,因为执行检查后的毫秒数可能不再使用该文件,反之亦然。相反,您只需打开文件并在没有例外的情况下使用它。
– Sedat Kapanoglu
2011年1月4日在7:16
太糟糕了。NET不支持CAS。诸如TryOpenFile(Ref FileHandle)之类的返回成功/失败的东西。应始终有一种解决方法,而不是仅依靠异常处理。我想知道Microsoft Office是如何做到的。
– TamusJRoyce
2011年7月31日在22:37
这里要了解的关键是该API只是使用Windows API来获取文件句柄。因此,他们需要转换从C API收到的错误代码,并将其包装为引发异常。 .Net中有异常处理,所以为什么不使用它。这样,您可以在代码中编写干净的转发路径,并将错误处理留在单独的代码路径中。
– Spence
2011年8月1日23:52
using语句是确保完成后关闭流。我认为您会发现using(){}比最终尝试{}少了{obj.Dispose()}字符。您还会发现,现在需要在using语句之外声明对象引用,这是一种更多的输入。如果您有一个明确的接口,则还必须强制转换。最后,您要尽快处置,并且最后的逻辑可能具有UI或任何其他长时间运行的动作,这些动作与调用IDispose无关。 rant>
– Spence
2012年11月27日在20:01
但这并不能否认您必须在try之外声明对象并必须显式调用dispose,而using对您而言意味着相同。
– Spence
13年1月31日,0:27
#3 楼
使用此命令检查文件是否已锁定:using System.IO;
using System.Runtime.InteropServices;
internal static class Helper
{
const int ERROR_SHARING_VIOLATION = 32;
const int ERROR_LOCK_VIOLATION = 33;
private static bool IsFileLocked(Exception exception)
{
int errorCode = Marshal.GetHRForException(exception) & ((1 << 16) - 1);
return errorCode == ERROR_SHARING_VIOLATION || errorCode == ERROR_LOCK_VIOLATION;
}
internal static bool CanReadFile(string filePath)
{
//Try-Catch so we dont crash the program and can check the exception
try {
//The "using" is important because FileStream implements IDisposable and
//"using" will avoid a heap exhaustion situation when too many handles
//are left undisposed.
using (FileStream fileStream = File.Open(filePath, FileMode.Open, FileAccess.ReadWrite, FileShare.None)) {
if (fileStream != null) fileStream.Close(); //This line is me being overly cautious, fileStream will never be null unless an exception occurs... and I know the "using" does it but its helpful to be explicit - especially when we encounter errors - at least for me anyway!
}
}
catch (IOException ex) {
//THE FUNKY MAGIC - TO SEE IF THIS FILE REALLY IS LOCKED!!!
if (IsFileLocked(ex)) {
// do something, eg File.Copy or present the user with a MsgBox - I do not recommend Killing the process that is locking the file
return false;
}
}
finally
{ }
return true;
}
}
public static byte[] ReadFileBytes(string filePath)
{
byte[] buffer = null;
try
{
using (FileStream fileStream = File.Open(filePath, FileMode.Open, FileAccess.ReadWrite, FileShare.None))
{
int length = (int)fileStream.Length; // get file length
buffer = new byte[length]; // create buffer
int count; // actual number of bytes read
int sum = 0; // total number of bytes read
// read until Read method returns 0 (end of the stream has been reached)
while ((count = fileStream.Read(buffer, sum, length - sum)) > 0)
sum += count; // sum is a buffer offset for next reading
fileStream.Close(); //This is not needed, just me being paranoid and explicitly releasing resources ASAP
}
}
catch (IOException ex)
{
//THE FUNKY MAGIC - TO SEE IF THIS FILE REALLY IS LOCKED!!!
if (IsFileLocked(ex))
{
// do something?
}
}
catch (Exception ex)
{
}
finally
{
}
return buffer;
}
public static string ReadFileTextWithEncoding(string filePath)
{
string fileContents = string.Empty;
byte[] buffer;
try
{
using (FileStream fileStream = File.Open(filePath, FileMode.Open, FileAccess.ReadWrite, FileShare.None))
{
int length = (int)fileStream.Length; // get file length
buffer = new byte[length]; // create buffer
int count; // actual number of bytes read
int sum = 0; // total number of bytes read
// read until Read method returns 0 (end of the stream has been reached)
while ((count = fileStream.Read(buffer, sum, length - sum)) > 0)
{
sum += count; // sum is a buffer offset for next reading
}
fileStream.Close(); //Again - this is not needed, just me being paranoid and explicitly releasing resources ASAP
//Depending on the encoding you wish to use - I'll leave that up to you
fileContents = System.Text.Encoding.Default.GetString(buffer);
}
}
catch (IOException ex)
{
//THE FUNKY MAGIC - TO SEE IF THIS FILE REALLY IS LOCKED!!!
if (IsFileLocked(ex))
{
// do something?
}
}
catch (Exception ex)
{
}
finally
{ }
return fileContents;
}
public static string ReadFileTextNoEncoding(string filePath)
{
string fileContents = string.Empty;
byte[] buffer;
try
{
using (FileStream fileStream = File.Open(filePath, FileMode.Open, FileAccess.ReadWrite, FileShare.None))
{
int length = (int)fileStream.Length; // get file length
buffer = new byte[length]; // create buffer
int count; // actual number of bytes read
int sum = 0; // total number of bytes read
// read until Read method returns 0 (end of the stream has been reached)
while ((count = fileStream.Read(buffer, sum, length - sum)) > 0)
{
sum += count; // sum is a buffer offset for next reading
}
fileStream.Close(); //Again - this is not needed, just me being paranoid and explicitly releasing resources ASAP
char[] chars = new char[buffer.Length / sizeof(char) + 1];
System.Buffer.BlockCopy(buffer, 0, chars, 0, buffer.Length);
fileContents = new string(chars);
}
}
catch (IOException ex)
{
//THE FUNKY MAGIC - TO SEE IF THIS FILE REALLY IS LOCKED!!!
if (IsFileLocked(ex))
{
// do something?
}
}
catch (Exception ex)
{
}
finally
{
}
return fileContents;
}
试试看:
byte[] output1 = Helper.ReadFileBytes(@"c:\temp\test.txt");
string output2 = Helper.ReadFileTextWithEncoding(@"c:\temp\test.txt");
string output3 = Helper.ReadFileTextNoEncoding(@"c:\temp\test.txt");
评论
如果那里没有太多的“魔术数字”,我会投票赞成。en.wikipedia.org/wiki/Magic_number_(programming)
–克里斯
13年3月11日在21:27
我指的是errorCode比较,而不是移位。虽然现在你提到了...
–克里斯
13年3月15日在9:35
您的Catch应该在IOException上,而不是在常规Exception上,然后在类型上进行测试。
–阿斯科林
13年4月22日在14:31
@JeremyThompson可悲的是,您将特定的IOException放在了一般的IException之后。一般的将捕获所有经过的东西,而特定的IOException将始终是孤独的。只需将两者交换即可。
–阿斯科林
13年6月18日在13:48
我喜欢这个解决方案。另一个建议是:在catch中插入if(IsFileLocked(ex)),否则我将抛出ex。然后,这将通过引发异常来处理文件不存在(或任何其他IOException)的情况。
– shindigo
14年4月18日在20:33
#4 楼
也许您可以使用FileSystemWatcher来监视Changed事件。我自己没有使用过,但是值得一试。如果在这种情况下filesystemwatcher有点沉重,那么我将进行try / catch / sleep循环。
评论
使用FileSystemWatcher没有帮助,因为Created和Changed事件在文件创建/更改的开始时引发。与.NET应用程序通过FileSystemEventHandler回调运行所需的时间相比,甚至小文件也需要更多的时间来由操作系统写入和关闭。这太可悲了,但是除了估计访问文件或进入异常循环之前的等待时间外,没有其他选择。
–user219337
2011年7月8日在12:29
但是FileSystemWatcher不能很好地同时处理很多更改,因此请务必谨慎。
– Ben F
2012年6月20日7:59
顺便说一句,你们在调试和观看线程时是否注意到MS将其自己的FSW称为“ FileSystemWather”?反正是个老婆?
–开发者
13年4月22日在0:29
恰好我遇到了这个问题,因为带有FileSystemWatcher的Windows服务尝试在进程关闭文件之前读取文件。
– freedeveloper
18年8月8日在15:09
#5 楼
只需按预期使用异常即可。接受该文件正在使用中,然后重试,直到操作完成。这也是最有效的,因为您在执行操作之前不会浪费任何时间检查状态。使用下面的函数,例如
TimeoutFileAction(() => { System.IO.File.etc...; return null; } );
可重复使用的方法在2秒后超时
private T TimeoutFileAction<T>(Func<T> func)
{
var started = DateTime.UtcNow;
while ((DateTime.UtcNow - started).TotalMilliseconds < 2000)
{
try
{
return func();
}
catch (System.IO.IOException exception)
{
//ignore, or log somewhere if you want to
}
}
return default(T);
}
#6 楼
您可以返回一个任务,该任务将在流可用时立即为您提供流。这是一个简化的解决方案,但这是一个很好的起点。它是线程安全的。private async Task<Stream> GetStreamAsync()
{
try
{
return new FileStream("sample.mp3", FileMode.Open, FileAccess.Write);
}
catch (IOException)
{
await Task.Delay(TimeSpan.FromSeconds(1));
return await GetStreamAsync();
}
}
您可以照常使用此流:
using (var stream = await FileStreamGetter.GetStreamAsync())
{
Console.WriteLine(stream.Length);
}
评论
从GetStreamAsync()的递归中堆栈溢出之前需要多少秒?
– CAD bloke
17年7月24日在11:14
@CADbloke,您提出了一个非常好的观点。的确,如果文件长时间不可用,我的示例可能会有堆栈溢出异常。与此答案stackoverflow.com/questions/4513438/…相关,它可能会在5小时内引发异常。
–伊凡·布雷内斯(Ivan Branets)
17年7月26日在8:51
与您的用例相关,如果假设10次读取文件的尝试失败,则最好抛出I / O异常。一旦10次尝试失败,另一种策略可能是增加等待一秒钟的时间。您也可以将两者混合使用。
–伊凡·布雷内斯(Ivan Branets)
17年7月26日在8:59
我会(并确实)只是警告用户文件已锁定。他们通常会自己锁定它,因此他们可能会对此做一些事情。或不。
– CAD bloke
17年7月26日在12:25
在某些情况下,您可能需要使用重试策略,因为文件可能尚未准备好。想象一下一个桌面应用程序在某个临时文件夹中下载图像。该应用程序开始下载,同时您在文件浏览器中打开此文件夹。 Windows希望立即创建缩略图并锁定文件。同时,您的应用程序尝试将锁定的图像替换到其他位置。如果您不使用重试策略,您将收到一个例外。
–伊凡·布雷内斯(Ivan Branets)
17年7月31日在13:16
#7 楼
我知道的唯一方法是使用不太快的Win32独占锁定API,但是存在示例。循环。评论
您必须先打开文件才能使用此API,此时不再需要该文件。
–哈里·约翰斯顿(Harry Johnston)
17年7月7日在21:15
薛定inger的档案。
–TheLastGIS
2月18日8:45
#8 楼
static bool FileInUse(string path)
{
try
{
using (FileStream fs = new FileStream(path, FileMode.OpenOrCreate))
{
fs.CanWrite
}
return false;
}
catch (IOException ex)
{
return true;
}
}
string filePath = "C:\Documents And Settings\yourfilename";
bool isFileInUse;
isFileInUse = FileInUse(filePath);
// Then you can do some checking
if (isFileInUse)
Console.WriteLine("File is in use");
else
Console.WriteLine("File is not in use");
希望有帮助!
评论
您执行的实际检查很好。将其放在函数中会产生误导。您不希望在打开文件之前使用此类功能。在函数内部,将打开,检查和关闭文件。然后,程序员假定该文件仍然可以使用,并尝试打开该文件以供使用。这很不好,因为它可能被排队打开该文件的另一个进程使用和锁定。在第一次打开(用于检查)和第二次打开(用于使用)之间,操作系统可能已经调度了您的进程,并且可能正在运行另一个进程。
– Lakey
2013年3月25日19:50
#9 楼
上面接受的答案会遇到以下问题:如果已打开文件以使用FileShare.Read模式进行写入,或者文件具有“只读”属性,则代码将不起作用。修改后的解决方案最可靠地工作,需要牢记两点(对于公认的解决方案也是如此):它不适用于已使用写共享打开的文件模式
这没有考虑线程问题,因此您需要将其锁定或单独处理线程问题。
请牢记以上内容,这将检查文件是否被锁定写入或锁定以防止读取:
public static bool FileLocked(string FileName)
{
FileStream fs = null;
try
{
// NOTE: This doesn't handle situations where file is opened for writing by another process but put into write shared mode, it will not throw an exception and won't show it as write locked
fs = File.Open(FileName, FileMode.Open, FileAccess.ReadWrite, FileShare.None); // If we can't open file for reading and writing then it's locked by another process for writing
}
catch (UnauthorizedAccessException) // https://msdn.microsoft.com/en-us/library/y973b725(v=vs.110).aspx
{
// This is because the file is Read-Only and we tried to open in ReadWrite mode, now try to open in Read only mode
try
{
fs = File.Open(FileName, FileMode.Open, FileAccess.Read, FileShare.None);
}
catch (Exception)
{
return true; // This file has been locked, we can't even open it to read
}
}
catch (Exception)
{
return true; // This file has been locked
}
finally
{
if (fs != null)
fs.Close();
}
return false;
}
评论
仍然存在与已接受答案相同的问题-它仅告诉您文件是否在某个特定时刻被另一个进程锁定,这不是有用的信息。到函数返回时,结果可能已经过时了!
–哈里·约翰斯顿(Harry Johnston)
2015年10月16日19:57
没错,一个人只能在任何给定的时间进行检查(或订阅事件),这种方法相对于公认的解决方案的优势在于它可以检查只读属性和写锁定,而不会返回假肯定。
–rboy
15-10-17在3:03
#10 楼
除了可以使用的3层衬纸,仅供参考:如果您需要完整的信息-Microsoft Dev Center上有一个小项目:https://code.msdn.microsoft.com/windowsapps / how-to-know-the-process-704839f4
从简介:
.NET Framework 4.0中开发的C#示例代码将有助于br />找出哪个进程锁定了文件。
rstrtmgr.dll中包含的RmStartSession函数已被
用于创建重启管理器会话并根据return <结果创建了Win32Exception对象的新实例。通过
RmRegisterRescources函数将资源注册到Restart Manager会话后,将调用RmGetList函数以通过枚举RM_PROCESS_INFO数组来检查哪些应用程序正在使用特定文件。
通过连接到“重新启动管理器会话”来工作。
重新启动管理器使用在会话中注册的资源列表来
确定必须关闭并重新启动哪些应用程序和服务。
资源可以通过文件名,服务简称或描述运行中的应用程序的RM_UNIQUE_PROCESS结构来标识。
可能会针对您的特定需求进行一些过度的设计...
但是如果您要这样做,请继续进行vs项目。
#11 楼
我曾经需要将PDF上传到在线备份档案中。但是,如果用户在另一个程序(例如PDF阅读器)中打开了文件,则备份将失败。我匆忙地尝试了该线程中的一些最佳答案,但未能使它们起作用。对我有用的是尝试将PDF文件移动到其自己的目录。我发现如果在另一个程序中打开文件,这将失败,并且如果移动成功,则不需要还原操作,就像将其移动到单独的目录一样。我想发布我的基本解决方案,以防它对其他人的特定用例有用。#12 楼
以我的经验,您通常想要这样做,然后“保护”文件以做一些花哨的事情,然后使用“受保护”的文件。如果只有这样一个文件要使用,则可以使用Jeremy Thompson答案中解释的技巧。但是,如果您尝试对许多文件执行此操作(例如,例如在编写安装程序时),那么您将受到相当大的伤害。可以通过以下事实来解决:使用文件系统不允许更改文件夹名称(如果正在使用该文件的其中一个文件)。将文件夹保存在同一文件系统中,它将像超级按钮一样工作。
请注意,您应该意识到可以利用此文件夹的明显方法。毕竟,文件不会被锁定。另外,请注意还有其他原因可能导致您的
Move
操作失败。显然,正确的错误处理(MSDN)可以在这里提供帮助。var originalFolder = @"c:\myHugeCollectionOfFiles"; // your folder name here
var someFolder = Path.Combine(originalFolder, "..", Guid.NewGuid().ToString("N"));
try
{
Directory.Move(originalFolder, someFolder);
// Use files
}
catch // TODO: proper exception handling
{
// Inform user, take action
}
finally
{
Directory.Move(someFolder, originalFolder);
}
对于单个文件,我会坚持Jeremy Thompson发表的锁定建议。
评论
嗨,由于答案的顺序发生了变化,因此您可以弄清楚上面哪个帖子对这个受欢迎的质量检查的读者意味着什么。谢谢。
–杰里米·汤普森(Jeremy Thompson)
2014年11月21日,11:02
@JeremyThompson您说得对,谢谢,我将编辑帖子。我会使用您的解决方案,主要是因为您正确使用了FileShare并检查了锁。
– atlaste
2014年11月21日上午11:09
#13 楼
据我所知,这是一些代码,它与接受的答案具有相同的功能,但是代码更少: public static bool IsFileLocked(string file)
{
try
{
using (var stream = File.OpenRead(file))
return false;
}
catch (IOException)
{
return true;
}
}
但是我认为它对请按照以下方式进行操作:
public static void TryToDoWithFileStream(string file, Action<FileStream> action,
int count, int msecTimeOut)
{
FileStream stream = null;
for (var i = 0; i < count; ++i)
{
try
{
stream = File.OpenRead(file);
break;
}
catch (IOException)
{
Thread.Sleep(msecTimeOut);
}
}
action(stream);
}
#14 楼
您可以使用我的库从多个应用程序访问文件。可以从nuget进行安装:Install-Package Xabe.FileLock
如果需要有关它的更多信息,请检查<
https://github.com/tomaszzmuda/Xabe.FileLock
ILock fileLock = new FileLock(file);
if(fileLock.Acquire(TimeSpan.FromSeconds(15), true))
{
using(fileLock)
{
// file operations here
}
}
fileLock.Acquire方法仅在可以锁定该对象专有文件的情况下才返回true。
但是上传文件的应用程序也必须在文件锁定中进行操作。
如果无法访问对象,方法返回false。
评论
要求使用该文件的所有进程进行协作。不太可能适用于OP的原始问题。
–哈里·约翰斯顿(Harry Johnston)
17年7月7日在21:17
#15 楼
我很想看看这是否会触发任何WTF反射。我有一个从控制台应用程序创建并随后启动PDF文档的过程。但是,我正在处理一个脆弱的问题,即如果用户要多次运行该进程,而没有先关闭先前生成的文件就生成相同的文件,则该应用程序将引发异常并死亡。这是一个很常见的情况,因为文件名基于销售报价编号。我不是依靠这种不友好的方式失败,而是决定依靠自动递增的文件版本控制:
private static string WriteFileToDisk(byte[] data, string fileName, int version = 0)
{
try
{
var versionExtension = version > 0 ? $"_{version:000}" : string.Empty;
var filePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, $"{fileName}{versionExtension}.pdf");
using (var writer = new FileStream(filePath, FileMode.Create))
{
writer.Write(data, 0, data.Length);
}
return filePath;
}
catch (IOException)
{
return WriteFileToDisk(data, fileName, ++version);
}
}
也许可以给
catch
块更多的注意,以确保我捕获到正确的IOException。我可能还会在启动时清除应用程序存储,因为这些文件无论如何都是临时文件。我意识到这超出了OP仅检查文件是否正在使用的问题的范围。但这确实是我到达这里时想要解决的问题,因此也许对其他人很有用。
#16 楼
retry_possibility:
//somecode here
try
{
using(FileStream stream = file.Open(FileMode.Open, FileAccess.Read, FileShare.None))
{
stream.Close();
}
//write or open your file here
}
catch (IOException)
{
DialogResult dialogResult = MessageBox.Show("This file is opened by you or another user. Please close it and press retry.\n"+ expFilePath, "File Locked", MessageBoxButtons.RetryCancel);
if (dialogResult == DialogResult.Retry)
{
goto retry_possibility;
}
else if (dialogResult == DialogResult.Cancel)
{
//do nothing
}
}
#17 楼
这样会有帮助吗?var fileWasWrittenSuccessfully = false;
while (fileWasWrittenSuccessfully == false)
{
try
{
lock (new Object())
{
using (StreamWriter streamWriter = new StreamWriter("filepath.txt"), true))
{
streamWriter.WriteLine("text");
}
}
fileWasWrittenSuccessfully = true;
}
catch (Exception)
{
}
}
#18 楼
尝试将文件移动/复制到临时目录。如果可以的话,它没有锁,您可以安全地在temp目录中工作而不会获得锁。否则,请尝试在x秒内再次移动它。评论
@jcolebrand锁什么?您复制的那个?还是您放入临时目录的那个?
– Cullub
2014年8月7日在17:23
如果您复制文件,希望没有其他人在处理它,并且您将使用临时文件,那么在复制文件后有人立即将其锁定,则可能会丢失数据。
– jcolebrand
2014年8月7日在21:07
#19 楼
我使用这种解决方法,但是当我使用IsFileLocked函数检查文件锁定与打开文件之间有一个时间间隔。在此时间范围内,其他一些线程可以打开文件,因此我将获得IOException。因此,我为此添加了额外的代码。就我而言,我想加载XDocument:
XDocument xDoc = null;
while (xDoc == null)
{
while (IsFileBeingUsed(_interactionXMLPath))
{
Logger.WriteMessage(Logger.LogPrioritet.Warning, "Deserialize can not open XML file. is being used by another process. wait...");
Thread.Sleep(100);
}
try
{
xDoc = XDocument.Load(_interactionXMLPath);
}
catch
{
Logger.WriteMessage(Logger.LogPrioritet.Error, "Load working!!!!!");
}
}
您怎么看?我可以改变一些东西吗?也许我根本不需要使用IsFileBeingUsed函数?
谢谢
评论
什么是IsFileBeingUsed? IsFileBeingUsed的源代码?
– Kiquenet
13年7月30日在6:01
评论
好的,您可以通过检查系统上所有打开的手柄来对其进行测试。但是,由于Windows是多任务操作系统,因此有可能在您运行代码以确定文件是否打开并且您认为未打开文件之后,进程代码便开始使用该文件,然后尝试进行操作。使用它,您会收到一个错误。但是,先检查没有错;只是不要以为在您真正需要它时就不会使用它。但是仅针对此特定问题;我建议不要检查文件句柄,而要尝试一些预设次数,例如3-5次,然后再失败。
如何生成此图像文件?在生成完成之前,您可以停止/睡眠/暂停程序吗?到目前为止,这是处理情况的一种上乘方式。如果没有,那么我认为您不能避免使用异常处理。
难道不是所有人都在例外情况下进行检查,通过做一些潜在的危险而故意不排除失败的可能性吗?
您的哲学对例外有不好的理解。大多数人认为例外意味着将错误的骰子骰子模样丢掉。当异常意味着...异常时。这意味着您需要“处理”(或说明)异常情况。也许您想继续尝试进行数据访问,也许用户需要知道您无法获得连接。你是做什么?您可以处理ConnectionFailedException并通知用户,因此,一个小时后他们可能会停止尝试,并注意到电缆已拔下。