1

我想以随机访问的方式打开一个键入的文件。这是通过设置FileModein来完成的fmOpenReadWrite。这要求文件存在,我测试文件是否存在,如果不存在,ReWrite则关闭它。请参阅下面的代码。

  var fl: file of _some_record_type_;
      fn: string;

  AssignFile (fl, fn);
  if not FileExists (fn) then
  begin
     ReWrite (fl);
     CloseFile (fl); // Now an empty file exists
  end; // if

  FileMode := fmOpenReadWrite;
  Reset (FTrack_File);
  // ...further rad and write operations...

这很好用,除非fn是非法文件名,例如在指定不存在的驱动器时。它在ReWrite. 我无法通过包围ReWriteby从错误中恢复,try..except因为对该文件或任何其他文件的任何引用都会引发访问冲突异常。似乎已经设置了一些条件来阻止任何文件 i/o。

有人知道如何处理这种情况吗?

4

1 回答 1

1

您可以切换到使用异常(使用{$I+}),然后使用try..except. (它通常是默认设置,除非您I/O Checking在“项目选项”对话框(Project->Options->Delphi Compiler->Compiling->Runtime Errors->I/O checking从主菜单中)中取消选中。

如果未选中该框,它会设置选项{$I-},它使用IOResult

如果您想继续使用IOResult,您需要在使用文件功能后进行检查。检查它会自动将 InOutRes 变量重置为0,清除先前的错误值。

AssignFile (fl, fn);
if not FileExists (fn) then
begin
  ReWrite (fl);
  if IOResult <> 0 then
    // You've had an error.
  CloseFile (fl); // Now an empty file exists
end; // if

IOResult可以在System单位找到。

You really should be moving away from the old style IO routines, BTW. They're ancient, and don't properly work with Unicode data. You can accomplish the same thing using a TFileStream, which would give you proper exception handling and support for Unicode. Here's a quick console app sample (tested with XP3 on Win 7):

program Project1;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils, Classes, Windows;

type
  TMyRec = record
    anInt: Integer;
    aBool: Boolean;
    aByte: Byte;
  end;

var
  FS: TFileStream;
  MyRec: TMyRec;
const
  TheFile = 'C:\TempFiles\test.dat';

begin
  MyRec.anInt := 12345;
  MyRec.aBool := True;
  MyRec.aByte := 128;
  FS := TFileStream.Create(TheFile, fmCreate or fmOpenReadWrite);
  try
    FS.Write(MyRec, SizeOf(TMyRec));
    // Clear the content and confirm it's been cleared
    FillChar(MyRec, SizeOf(TMyRec), 0);
    WriteLn('anInt: ', MyRec.anInt, ' aBool: ', MyRec.aBool, ' aByte: ', MyRec.aByte);

    FS.Position := 0;
    FS.Read(MyRec, SizeOf(TMyRec));
  finally
    FS.Free;
  end;
  // Confirm it's read back in properly
  WriteLn('anInt: ', MyRec.anInt, ' aBool: ', MyRec.aBool, ' aByte: ', MyRec.aByte);
  ReadLn;
end.
于 2013-04-08T13:58:33.163 回答