[英]Delphi: File access and compatibility files (windows 7)
假設我的應用程序名為mysoft
,而我想讀取的文件是afile.bin
。 mysoft
位於程序文件夾中。 我們還假設沒有使用管理員權限執行mysoft。
procedure TForm1.Button1Click(Sender: TObject);
var
afile: File of Byte;
begin
AssignFile(Infile, 'C:\Program Files\mysoft\afile.bin');
Reset(afile);
CloseFile(afile);
end;
上面的簡單代碼將在兼容性文件文件夾中創建afile.bin
的副本。
我的問題是:
我再次只閱讀數據文件,我不明白。
對Reset
的調用導致文件被打開以進行寫入。 那是因為System.FileMode
的默認值是fmOpenReadWrite
。 由於您的應用程序運行虛擬化,並且由於您的用戶令牌沒有管理員權限,因此虛擬化層會啟動並在虛擬存儲中創建該文件的副本。
使用傳統Pascal I / O可用的解決方案是將FileMode
設置為fmOpenRead
。 然后Reset
將打開文件以供讀取,並且不會調用虛擬化層。
請記住, FileMode
是一個影響所有傳統Pascal I / O的全局變量。 如果你有線程,或者忘記在需要編寫文件時忘記將FileMode
設置回fmOpenReadWrite
,那么你會fmOpenReadWrite
。 反叛不是嗎? 處理廣泛的全局標志以控制文件訪問模式! 好吧,這些東西是在應用程序有線程之前發明的。 早在OOP發明之前。 所以我能理解為什么會這樣。
從中汲取的教訓是,現在是時候切換到一種現代形式的文件訪問。 例如, TFileStream
。
實際上,也是您在應用程序中禁用虛擬化的時候了。 近6年前,Vista中引入了虛擬化。 這對於尚未針對Vista進行重新編譯的舊程序來說是一種幫助。 您的應用程序不應該仍在使用它。
如果您有一個支持TStreamReader類的Delphi版本,並且您的文件是文本,則可以使用以下代碼:
procedure TForm1.btn1Click(Sender: TObject);
var
SR : TStreamReader;
line : string;
begin
SR := TStreamReader.Create('C:\Program Files\mysoft\afile.bin');
try
while not SR.EndOfStream do
begin
line := SR.ReadLine;
end;
finally
SR.Free;
end;
end;
如果不是,我建議一種適用於任何文件的更經典的方法:
procedure TForm1.btn2Click(Sender: TObject);
var
FS : TFileStream;
mem : array of byte;
begin
FS := TFileStream.Create('C:\Program Files\mysoft\afile.bin',fmOpenRead or fmShareDenyNone);
try
SetLength(mem,FS.Size);
FS.Read(mem[0],FS.Size);
finally
FS.Free;
end;
end;
我相信這是因為Windows 7的“ 新功能 ”,它不允許您直接訪問文件系統區域中的文件(%programfiles%,%systemroot%,%systemdrive%或%programdata%)。
嘗試使用TFileStream
將代碼更改為打開文件,並將Mode設置為fmOpenRead
。
我希望它有效。 我沒有7試試 :)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.