4 Stimmen

Delphi: Dateizugriff und Kompatibilitätsdateien (Windows 7)

Nehmen wir an, meine Anwendung heißt mysoft und die Datei, die ich LESEN möchte, lautet afile.bin . mysoft befindet sich im Programmordner. Nehmen wir außerdem an, dass mysoft nicht mit Admin-Rechten ausgeführt wird.

procedure TForm1.Button1Click(Sender: TObject);
var 
  afile: File of Byte;
begin
  AssignFile(Infile, 'C:\Program Files\mysoft\afile.bin');
  Reset(afile);
  CloseFile(afile);
end;

Der obige einfache Code erstellt eine Kopie von afile.bin im Ordner Kompatibilitätsdateien.

Meine Fragen sind:

  1. Warum? Ich lese die verdammte Datei nur, ich will sie nicht verändern.
  2. Wie kann man dies verhindern, außer durch Verschieben der Datei in einen anderen Ordner?

Auch hier habe ich nur die Datei gelesen, ich verstehe es nicht.

5voto

David Heffernan Punkte 585606

Die Aufforderung an Reset führt dazu, dass die Datei zum Schreiben geöffnet wird. Das liegt daran, dass der Standardwert von System.FileMode es fmOpenReadWrite . Da Ihre Anwendung virtualisiert ausgeführt wird und Ihr Benutzer-Token keine Administratorrechte hat, greift die Virtualisierungsschicht ein und erstellt eine Kopie der Datei im virtuellen Speicher.

Die Lösung, die bei der Verwendung von Legacy-Pascal-I/O verfügbar ist, besteht darin, die FileMode a fmOpenRead . Dann Reset wird die Datei zum Lesen geöffnet und die Virtualisierungsschicht wird nicht aufgerufen.

Denken Sie daran, dass FileMode ist eine globale Variable, die alle Legacy-Pascal-E/A beeinflusst. Wehe, wenn Sie Threads haben, oder vergessen, die Variable FileMode zurück zu fmOpenReadWrite wenn Sie eine Datei schreiben müssen. Widerlich, nicht wahr? Prozessweite globale Flags zur Steuerung des Dateizugriffsmodus! Nun, dieses Zeug wurde erfunden, lange bevor Anwendungen Threads hatten. Und lange bevor OOP erfunden wurde. Ich kann also verstehen, warum das so ist.

Daraus lässt sich die Lehre ziehen, dass es an der Zeit ist, auf eine der modernen Formen des Dateizugriffs umzusteigen. Zum Beispiel, TFileStream .

In der Tat ist es auch an der Zeit, die Virtualisierung in Ihrer Anwendung zu deaktivieren. Die Virtualisierung wurde vor fast 6 Jahren mit Vista eingeführt. Sie war als Hilfe für alte Programme gedacht, die noch nicht für Vista neu kompiliert worden waren. Ihre Anwendung sollte sie nicht mehr verwenden.

2voto

opc0de Punkte 11342

Wenn Sie eine Version von Delphi haben, die die TStreamReader-Klasse unterstützt und Ihre Datei ein Text ist, können Sie diesen Code verwenden:

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;

Falls nicht, schlage ich einen klassischeren Ansatz vor, der mit jeder Datei funktioniert:

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;

0voto

sybond Punkte 167

Ich glaube, das liegt daran, dass die Windows 7 " neue Funktion ", was Ihnen den direkten Zugriff auf eine Datei im Dateisystembereich (%programfiles%, %systemroot%, %systemdrive% oder %programdata%) verwehrt.

Versuchen Sie, Ihren Code so zu ändern, dass die Datei mit TFileStream und stellen Sie Modus auf fmOpenRead .

Ich hoffe, es funktioniert. Ich habe keine 7 um es zu versuchen :)

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X