我需要读取可能被锁定的Windows文件,但我不想创建任何类型的锁,以防止其他进程写入该文件。
此外,即使文件被锁定以供独家使用,我也希望看到里面的内容。
虽然这不是我的确切用例,但请考虑如何在使用和装载时读取SQL / Exchange日志或数据库文件。我不想导致腐败,但我仍然希望看到文件的内部并阅读它。
答案 0 :(得分:47)
您可以在不复制文件的情况下执行此操作,请参阅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);
}
}
答案 1 :(得分:15)
接受的答案不正确。如果文件确实被锁定,则不能只更改文件共享。如果已使用此文件共享选项设置了锁,但这并不意味着它就是这种情况。实际上,您可以通过在没有FileShare.ReadWrite的情况下打开文件来轻松地测试@CaffGeek解决方案,而不是尝试使用此标志将其打开到ReadWrite。你会得到另一个进程正在使用该文件。
代码:
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();
}
}
如你所见,它崩溃了。此结果与File.Open等任何FileStream方法相同。它会在开放阶段崩溃你为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而不仅仅是FileShare .WRITE。
答案 2 :(得分:1)
即使文件被锁定,您也可以创建一个副本并读取它。
或者FileStream上的StreamReader可能取决于SQL如何打开文件?
new FileStream("c:\myfile.ext", FileMode.Open, FileAccess.Read, FileShare.ReadWrite);