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を囲んでエラーから回復することはできません。ファイルの I/O を妨げる何らかの条件が設定されているようです。try..except

誰かがこの状況を処理する方法を知っていますか?

4

1 に答える 1

1

例外の使用に切り替えて ( を使用{$I+})、 を使用できますtry..except。(メイン メニューのI/O Checking[Project Options] ダイアログでチェックを外していない限り、通常はデフォルトです)。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

ところで、古いスタイルの IO ルーチンから離れるべきです。それらは古いものであり、Unicode データでは適切に機能しません。を使用して同じことを達成できTFileStreamます。これにより、適切な例外処理と Unicode のサポートが得られます。簡単なコンソール アプリのサンプルを次に示します (Win 7 上の XP3 でテスト済み)。

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 に答える