Why do I / O errors prevent exceptions?

I use Pascal's old-style I / O routines and expect I / O function calls that don't work should raise an EInOutError . When I try to do this, I see no exception, and I do not know why.

 procedure TForm1.Button1Click(Sender: TObject); //var i: integer; begin id:=(strtoint(Edit1.Text)-1)*4; AssignFile(plik,'\klienci\'+linia_klient[id]+'.txt'); try Reset(plik); except on EInOutError do Rewrite(plik); end; edit2.Text:=linia_klient[id+1]; edit3.Text:=linia_klient[id+2]; //ListBox1.Clear; //ListBox1.Items.Add(); end; 

Integer code:

 unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) Label1: TLabel; Edit1: TEdit; Button1: TButton; Label2: TLabel; Label3: TLabel; Edit2: TEdit; Edit3: TEdit; ListBox1: TListBox; Label4: TLabel; procedure FormCreate(Sender: TObject); procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; plik:TextFile; linia_klient,linia_video:array[0..20] of string; id:integer; implementation {$R *.dfm} {$IOCHECKS ON} procedure TForm1.FormCreate(Sender: TObject); var i:integer; begin Edit1.Text:='Witaj, Podaj ID klienta'; Label1.Caption:='ID'; AssignFile(plik,'klienci.txt'); Reset(plik); i:=0; While Not Eof(plik) do begin Readln(plik,linia_klient[i]); inc(i); end; CloseFile(plik); AssignFile(plik,'video.txt'); Reset(plik); i:=0; While Not Eof(plik) do begin Readln(plik,linia_video[i]); inc(i); end; CloseFile(plik); end; procedure TForm1.Button1Click(Sender: TObject); //var i: integer; begin id:=(strtoint(Edit1.Text)-1)*4; AssignFile(plik,'\klienci\'+linia_klient[id]+'.txt'); try Reset(plik); except on EInOutError do Rewrite(plik); end; edit2.Text:=linia_klient[id+1]; edit3.Text:=linia_klient[id+2]; //ListBox1.Clear; //ListBox1.Items.Add(); end; end. 
+6
source share
2 answers

An EInOutError exception will be raised only if I / O checking is enabled. To verify that it is turned on, follow these steps:

  • In the parameters of your project in "Delphi Compiler Parameters", check the checkbox of input / output
  • Remove any {$ IOCHECKS OFF} or {$ I-} directives from your code as they disable I / O checking

This should give you the correct exception if the file does not exist.

Now, if (for some reason) you cannot enable I / O checking:

If I / O checking is disabled, you will not get an EInOutError if something goes wrong. Instead, you should check the IOResult value after each I / O operation. This is similar to the old days of Pascal: if IOResult <> 0 , then an error occurred. This (slightly adapted) excerpt from Delphi docs shows how to work with IOResult:

  AssignFile(F, FileName); {$I-} Reset(F); {$I+} if IOResult = 0 then begin MessageDlg('File size in bytes: ' + IntToStr(FileSize(F)), mtInformation, [mbOk], 0); CloseFile(F); end else MessageDlg('File access error', mtWarning, [mbOk], 0); 

However, for now, you should use TFileStream to access / create files and no longer use the old Pascal routines. An example of how this might look:

 filename := '\klienci\'+linia_klient[id]+'.txt'; if not FileExists(filename) then // "Create a file with the given name. If a file with the given name exists, open the file in write mode." fs := TFileStream.Create(filename, fmCreate) else // "Open the file to modify the current contents rather than replace them." fs := TFileStream.Create(filename, fmOpenReadWrite); 
+8
source

I interpret your question that you would like EInOutError exceptions EInOutError occur whenever a Pascal-style I / O function fails. To do this, you need to enable the option to check the I / O check .

Check I / O. Enables or disables automatic code generation, which checks the result of an I / O procedure call. If the I / O procedure returns a non-zero I / O result when this switch is turned on, an EInOutError exception is thrown (or the program terminates if exception handling is not turned on). When this switch is off, you should check for I / O errors by calling IOResult.

I assume that the code you are working with was written under the assumption that the I / O check option was enabled, but that you are compiling with it, it is not enabled. Here's some code demonstrating an EInOutError that occurs due to an I / O error.

 program IOchecking; {$APPTYPE CONSOLE} {$IOCHECKS ON} uses SysUtils; var F: File; begin AssignFile(F, 'path/to/file/that/does/not/exist'); Reset(F);//raises EInOutError end. 

I highly recommend that you enable I / O checking. This will allow you to handle errors using exceptions according to the rest of your code.

IOResult not IOResult I / O checking, you can check the IOResult value after each I / O function. This is very error prone (it's easy to forget to check) and leads to fuzzy code.

If you are already using I / O checking, then the most likely explanation for not seeing the error is that the error does not actually occur. Perhaps the file really exists.

+5
source

Source: https://habr.com/ru/post/903589/


All Articles