如何判断文件是否打开一直是个很头疼的问题,幸好项目中只是要求文件lock,何为文件lock大致可以理解为文件正在编辑中,禁止其他人写人!
该文件为CSV文件,常规写法为:
TextFieldParser parser = new TextFieldParser(stream,System.Text.Encoding.GetEncoding("Shift_JIS"));
using (parser)
{
parser.TextFieldType = FieldType.Delimited;
parser.SetDelimiters(",");
while (!parser.EndOfData)
{
string[] row = parser.ReadFields();
csvDataList.Add(row);
}
}
如上可读出CSV文件中的数据,并且把同一行每个单元格的数据做成数组。
但是这种写法起不到lock的效果,查询MSDN发现TextFieldParser可以传入个Stream,如果以写文件的方式打开,出现Exception可能就是被lock住了
因此研究了三种解决方法
1,通过独占的方式打开文件
FileStream fileStream = new FileStream(filePathName, FileMode.Open, FileAccess.Read, FileShare.None);
byte[] bytes = new byte[fileStream.Length];
fileStream.Read(bytes, 0, bytes.Length);
fileStream.Close();
Stream stream = new MemoryStream(bytes);
TextFieldParser parser = new TextFieldParser(stream, System.Text.Encoding.GetEncoding("Shift_JIS"));
FileShare.None会以独占的方式对数据进行读取,这样就起到了lock的效果
2,通过写文件的方式判断
Stream stream = File.OpenWrite(filePathName);
stream.Dispose(); // 必须释放,否则读取文件会出Exception
这样如果文件打开,第一步就会出Exception就可以判断出来了。
3,通过API进行判断
[DllImport("kernel32.dll")]
private static extern IntPtr _lopen(string lpPathName, int iReadWrite);
[DllImport("kernel32.dll")]
private static extern bool CloseHandle(IntPtr hObject);
private const int OF_READWRITE = 2;
private const int OF_SHARE_DENY_NONE = 0x40;
private static IntPtr HFILE_ERROR = new IntPtr(-1);
public bool IsFileOpenByOtherProcess(string fileName)
{
File.OpenWrite(fileName);
IntPtr vHandle = _lopen(fileName, OF_READWRITE | OF_SHARE_DENY_NONE);
if (vHandle == HFILE_ERROR)
{
return true;
}
CloseHandle(vHandle);
return false;
}
但是用一般文本文档编辑工具(text,emEditor)打开并不算是lock,建议用sakura。
以上仅供参考!