我想打开一个类型化的文件作为随机访问。这是通过在FileMode
中设置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
引发了一个例外。我无法通过ReWrite
围绕try..except
来恢复错误,因为对该文件的任何引用或任何其他文件都会引发访问冲突异常。看来已经设置了一些阻止任何文件i / o的条件。
有人知道如何处理这种情况吗?
答案 0 :(得分:1)
您可以切换为使用例外(使用{$I+}
),然后使用try..except
。 (这通常是默认设置,除非您在“项目选项”对话框(主菜单中为I/O Checking
)中取消选中Project->Options->Delphi Compiler->Compiling->Runtime Errors->I/O checking
。
如果取消选中该框,则会设置使用IOResult
的选项{$I-}
。
如果您想继续使用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惯例BTW。它们很古老,并且不适合使用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.