【问题标题】:Delphi: File access and compatibility files (windows 7)Delphi:文件访问和兼容性文件(Windows 7)
【发布时间】:2012-10-01 04:24:21
【问题描述】:

假设我的应用名为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. 除了将文件移动到另一个文件夹之外,如何防止这种情况发生?

再次,我只读取了数据文件,我不明白。

【问题讨论】:

    标签: delphi windows-7


    【解决方案1】:

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

    使用传统 Pascal I/O 可用的解决方案是将 FileMode 设置为 fmOpenRead。然后Reset会打开文件进行读取,不会调用虚拟层。

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

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

    确实,也是时候在应用程序中禁用虚拟化了。近 6 年前,Vista 中引入了虚拟化。它旨在帮助尚未为 Vista 重新编译的旧程序。您的应用程序不应仍在使用它。

    【讨论】:

    • 我终于将代码转换为使用tfilestream,问题已经解决。谢谢
    • 别忘了也为您的应用禁用虚拟化。
    • David,您能详细说明如何禁用虚拟化吗?它是某个地方的编译器开关吗?
    • @Chris 在应用清单中指定requestedExecutionLevel。
    【解决方案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;
    

    【讨论】:

      【解决方案3】:

      我相信这是因为 Windows 7 的“新功能”不允许您直接访问文件系统区域中的文件(%programfiles%、%systemroot%、%systemdrive%、或 %programdata%)。

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

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

      【讨论】:

      • 标准用户也无法在 XP 中访问这些区域。 UAC 和虚拟化来自 Vista 而不是 7。
      猜你喜欢
      • 2010-11-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-19
      • 2011-02-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多