簡體   English   中英

Delphi:文件訪問和兼容性文件(Windows 7)

[英]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的副本。

我的問題是:

  1. 為什么? 我只讀了該死的文件,我不想修改它。
  2. 除了在另一個文件夾中移動文件之外,如何防止這種情況?

我再次只閱讀數據文件,我不明白。

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM