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.}
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 lockedreturn false;}
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 checkingif (isFileInUse)Console.WriteLine("File is in use");elseConsole.WriteLine("File is not in use");
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!!!!!");}}
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 exceptiontry {//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 filereturn 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 lengthbuffer = new byte[length]; // create bufferint count; // actual number of bytes readint 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 lengthbuffer = new byte[length]; // create bufferint count; // actual number of bytes readint 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 youfileContents = 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 lengthbuffer = new byte[length]; // create bufferint count; // actual number of bytes readint 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;}
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);}
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 lockedfs = 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 modetry{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;}
在. NET Framework 4.0中开发的C#示例代码将有助于找出哪个进程对文件有锁。RmStart会话开始时间包含在rstrtmgr.dll中的函数用于创建重启管理器会话,并根据返回结果创建了Win32Exception对象的新实例。之后通过将资源注册到重新启动管理器会话资源注册资源函数,调用获取资源列表函数检查通过枚举哪些应用程序正在使用特定文件RM_PROCESS_INFO数组。
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}}