Delphi:文件访问和兼容性文件(Windows 7)

时间:2012-10-10 16:06:34

标签: delphi windows-7

假设我的应用名为mysoft,而我想要阅读的文件为afile.binmysoft位于程序文件文件夹中。 我们还假设没有使用管理员权限执行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. 除了在另一个文件夹中移动文件外,如何防止这种情况?
  3. 我再次只阅读数据文件,我不明白。

3 个答案:

答案 0 :(得分:5)

Reset的调用导致文件被打开以进行写入。那是因为System.FileMode的默认值是fmOpenReadWrite。由于您的应用程序是虚拟化的,并且由于您的用户令牌没有管理员权限,因此虚拟化层会启动并在虚拟商店中创建该文件的副本。

使用旧版Pascal I / O提供的解决方案是将FileMode设置为fmOpenRead。然后Reset将打开文件进行读取,并且不会调用虚拟化层。

请记住,FileMode是一个影响所有传统Pascal I / O的全局变量。如果你有线程,或者忘记在需要写文件时忘记将FileMode设置回fmOpenReadWrite,那么你会感到很遗憾。反叛不是吗?处理广泛的全局标志以控制文件访问模式!好吧,这些东西是在应用程序有线程之前发明的。早在OOP发明之前。所以我可以理解为什么会这样。

要从中汲取的教训是,现在是时候切换到一种现代形式的文件访问。例如,TFileStream

确实,您也应该在应用程序中禁用虚拟化。近6年前,Vista中引入了虚拟化。这对于尚未针对Vista进行重新编译的旧程序来说是一种帮助。您的应用程序不应该仍在使用它。

答案 1 :(得分:2)

如果您的Delphi版本支持TStreamReader类,而您的文件是文本,则可以使用以下代码:

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;

答案 2 :(得分:0)

我认为这是因为Windows 7“新功能”,它禁止您直接访问文件系统区域中的文件(%programfiles%,%systemroot%,%systemdrive%,或%programdata%)。

尝试使用TFileStream将代码更改为打开文件,并将模式设置为fmOpenRead

我希望它有效。 我没有7尝试:)