【发布时间】:2010-08-24 20:14:35
【问题描述】:
我需要读取一个可能被锁定的 Windows 文件,但我不想创建任何会阻止其他进程写入文件的类型的锁。
另外,即使文件被锁定为独占使用,我也想看看里面有什么。
虽然这不是我的确切用例,但请考虑如何在 SQL/Exchange 日志或数据库文件正在使用和挂载时读取它。我不想造成损坏,但我仍然想查看文件的内部并阅读它。
【问题讨论】:
我需要读取一个可能被锁定的 Windows 文件,但我不想创建任何会阻止其他进程写入文件的类型的锁。
另外,即使文件被锁定为独占使用,我也想看看里面有什么。
虽然这不是我的确切用例,但请考虑如何在 SQL/Exchange 日志或数据库文件正在使用和挂载时读取它。我不想造成损坏,但我仍然想查看文件的内部并阅读它。
【问题讨论】:
不用复制文件也可以,见this文章:
诀窍是使用 FileShare.ReadWrite(来自文章):
private void LoadFile()
{
try
{
using(FileStream fileStream = new FileStream(
"logs/myapp.log",
FileMode.Open,
FileAccess.Read,
FileShare.ReadWrite))
{
using(StreamReader streamReader = new StreamReader(fileStream))
{
this.textBoxLogs.Text = streamReader.ReadToEnd();
}
}
}
catch(Exception ex)
{
MessageBox.Show("Error loading log file: " + ex.Message);
}
}
【讨论】:
接受的答案不正确。如果文件确实被锁定,则不能只更改文件共享。如果也使用此文件共享选项设置了锁定,这将起作用,但这并不意味着是这种情况。事实上,您可以通过打开不带FileShare.ReadWrite 的文件而不是尝试使用ReadWrite 的标志打开它来非常轻松地测试@CaffGeek 解决方案。您会发现该文件正在被另一个进程使用。
代码:
string content;
var filePath = "e:\\test.txt";
//Lock Exclusively the file
var r = File.Open(filePath, FileMode.Open, FileAccess.Write, FileShare.Write);
//CaffGeek solution
using (FileStream fileStream = new FileStream(
filePath,
FileMode.Open,
FileAccess.Read,
FileShare.ReadWrite))
{
using (StreamReader streamReader = new StreamReader(fileStream))
{
content = streamReader.ReadToEnd();
}
}
如您所见,它崩溃了。此结果与任何FileStream 方法(如File.Open)相同。它会使您在打开阶段为 FileShare 输入的内容崩溃。
//OPEN FOR WRITE with exclusive
var r = File.Open(filePath, FileMode.Open, FileAccess.Write, FileShare.Write);
//OPEN FOR READ with file share that allow read and write
var x = File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); //Crash
复制文件也不是一种选择。您可以通过独占打开文件并尝试在 Windows 资源管理器中复制文件或通过代码自行尝试:
var filePath = "e:\\test.txt";
var filePathCopy = "e:\\test.txt.bck";
//Lock the file
var r = File.Open(filePath, FileMode.Open, FileAccess.Write, FileShare.Write);
File.Copy(filePath, filePathCopy);
var x = File.Open(filePathCopy, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
using (var reader = new StreamReader(x))
{
content = reader.ReadToEnd();
}
r.Close();
File.Delete(filePathCopy);
当您点击File.Copy 行时,此代码会崩溃。异常与之前相同:文件正在被另一个进程使用。
如果你想读取文件,或者如果你有锁定文件的文件的源代码,你需要杀死拥有文件锁定的进程,以将这个文件更改为使用FileShare.ReadWrite 而不仅仅是@ 987654330@.
【讨论】:
即使文件被锁定,您也可以创建一个副本并阅读它。
或者可能是 FileStream 上的 StreamReader,具体取决于 SQL 如何打开文件?
new FileStream("c:\myfile.ext", FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
【讨论】: