2018编辑:如以下和其他来源所示,以创建者的更新或更高版本为目标允许对打开供另一个进程写入的文件进行只读文件访问.万岁!
尝试为桌面开发Windows Store应用程序时,我似乎遇到了麻烦.我正在尝试打开另一个应用程序已打开的大型(100 MB)日志文件,并对写入到文件中的最新事件进行实时处理.
使用常规的非沙盒C#,这非常简单:
System.IO.FileStream stream = File.Open("LOGFILE PATH HERE", System.IO.FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
不幸的是,在UWP中,每当我尝试打开另一个应用程序正在使用的文件时,都会收到“ UnauthorizedAccessException”.我尝试了所有可能找到的组合中的每个API,但是运气为零,因此我来这里提出一些建议.
我尝试过的一些方法:
Windows.Storage.Pickers.FileOpenPicker picker = new Windows.Storage.Pickers.FileOpenPicker();
picker.ViewMode = Windows.Storage.Pickers.PickerViewMode.List;
//Prompt the user to open the log file:
Windows.Storage.StorageFile logFile = await picker.PickSingleFileAsync();
picker.FileTypeFilter.Add(".txt");
//This won't work in any case, because it doesn't use the handle that the user picked,
// so the UWP sandboxing blocks it:
new FileStream(logFile.Path, FileMode.OpenOrCreate, FileAccess.Read);
//EDIT: These don't work if the file is open either, I must have made a mistake earlier
await FileIO.ReadBufferAsync(logFile);
await FileIO.ReadLinesAsync(logFile);
//These work if the file is not open by another app, but fail if another app has the file open
await logFile.OpenAsync( Windows.Storage.FileAccessMode.Read);
await logFile.OpenStreamForReadAsync();
快速复制:
打开PowerShell窗口,然后运行以下命令以在您的主目录中保持打开状态“ test.txt”:
$f = [System.IO.File]::Open("test.txt", [System.IO.FileMode]::OpenOrCreate, [System.IO.FileAccess]::Write, [System.IO.FileShare]::ReadWrite);
解决方法:
从周年更新开始,这是Universal API的预期行为. (又名RS1). Windows.Storage.* API和流使用所谓的“ Polite Reader”模型.在此模型中,读取器可能会被写入器打断,从而产生OPLOCK中断错误.在RS1中,这还意味着如果已经存在任何打开的写句柄,则会阻止读取器.
在创作者更新(又名RS2)中,此方面有些变化.随着通用平台从最初的WinRT演变为具有单个前景应用程序的情况,出现了允许应用程序使用更多传统模型的需求.因此,在RS2中,我们进行了一些更改以在这种情况下提供帮助.
>如果写者已经存在,则未修改的礼让型阅读器将不会再因打开而失败.但是,如果编写者实际写入文件,则读者仍然会遇到oplock中断.
>共享冲突会直接显示给呼叫者,而不是转换为AccessDenied. (出于兼容性考虑,此新行为在调用应用程序时被门控,在应用程序清单中将RS2声明为经过测试的平台)
>提供了新的StorageOpenOptions,以便应用程序可以更改其代码以使用新选项来获得不涉及oplock的行为,从而有效地退出OpLock行为.