首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在ReWrite失败后恢复?

如何在ReWrite失败后恢复?
EN

Stack Overflow用户
提问于 2013-04-08 11:03:43
回答 1查看 757关注 0票数 1

我想以随机访问的方式打开键入的文件。这是通过在FileMode中设置fmOpenReadWrite实现的。这要求文件存在,我测试该文件是否存在,如果不存在,请ReWrite并关闭它。请参阅下面的代码。

代码语言:javascript
复制
  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。

有人知道怎么处理这种情况吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-04-08 13:58:33

您可以切换到使用异常( {$I+}),然后使用try..except。(这通常是默认的,除非您在Project对话框(主菜单中的I/O Checking )中没有选中Project->Options->Delphi Compiler->Compiling->Runtime Errors->I/O checking)。

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

如果您想继续使用IOResult,则需要在使用文件函数之后检查它。检查它会自动将InOutRes变量重置为0,从而清除前面的错误值。

代码语言:javascript
复制
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进行测试):

代码语言:javascript
复制
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.
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15877470

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档