Jump to content

{$I-} / {$I+} - Gestão de erros ao lidar com ficheiros


nunopicado
 Share

Recommended Posts

Ora então boa tarde.

Trabalhar com ficheiros em Pascal é das coisas mais simples que há. Meia duzia de comandos, e faz-se tudo com ficheiros, sejam de texto, sequenciais, binários, etc.

No entanto, tenho reparado que muitos se esquecem de despistar erros, o que pode originar "gatos" durante a utilização do programa.

Actualmente, nas mais recentes implementações de Pascal, existe uma estrutura chamada Try... Except.

Com ela, podemos "tentar" abrir ou gravar um ficheiro, e se não for possivel, executar uma qualquer acção, como por exemplo informar o utilizador que não foi possível completar a operação.

var
   F:Text;
begin
   Assign(F,'c:\teste.txt');
   Try
      Reset(F);
   Except
      Writeln('O ficheiro não existe ou não foi possível aceder-lhe. . .');
   End;
.
.
.
end,

Tão simples como isto e temos o erro gerido.

Mas... e antes de haver a estrutura Try... Except? Não se controlavam os erro?

Claro que sim, e entre uma e outra forma, não sei qual será a mais simples de implementar!

O compilador Pascal, logo à partida, tem um gestor de erros de Input/Output (erros tipicamente gerados por operações em ficheiros). Mas este gestor logicamente não sabe o que queremos fazer caso um erro seja encontrado. Como tal, apresenta simplesmente uma mensagem de erro, e crasha o programa.

Como bons programadores, não queremos crashes.

Então o que temos de fazer é desactivar o gestor de erros de IO do compilador, e criar o nosso proprio gestor.

Para tal, usa-se a directiva de compilado $I que activa e desactiva o gestor do compilador. Usa-se também uma função que devolve o código de erro gerado pela última operação de IO.

Assim, o programa anterior ficaria assim:

var
   F:Text;
begin
   Assign(F,'c:\teste.txt');
   {$i-} // Desactiva o gestor do compilador
   Reset(F);
   {$i+}  // Volta a activar o gestor do compilador

   if IOResult<>0   // Se o resultado de IOResult for 0, é porque não houve erro. Se for diferente de 0...
      then Writeln('O ficheiro não existe ou não foi possível aceder-lhe. . .');
.
.
.
end,

Basicamente é isto...

Como se pode ver, não custa nada programar correctamente quando se trabalha com ficheiros em Pascal...  🙂

"A humanidade está a perder os seus génios... Aristóteles morreu, Newton já lá está, Einstein finou-se, e eu hoje não me estou a sentir bem!"

> Não esclareço dúvidas por PM: Indica a tua dúvida no quadro correcto do forum.

Link to comment
Share on other sites

Já agora quem quiser esmerar-se e indicar ao seu utilizador não apenas um erro genérico mas o erro real aqui fica uma tabela de resultados da função IOResult.

Estes erros são para as funções que trabalham com ficheiros mas não só. Servem para todas as funções de IO (impressão por exemplo).

2 - Ficheiro não encontrado

3 - Caminho não encontrado

4 - Demasiados ficheiros abertos

5 - Acesso negado

6 - Handle de ficheiro inválido

12 - Mode de acesso a ficheiro inválido

15 - Número de disco inválido

16 - Não é possível eliminar a pasta actual

17 - Impossível renomear um ficheiro de um volume para outro

100 - Erro ao ler do disco

101 - Erro ao gravar no disco

102 - Ficheiro não atribuido

103 - Ficheiro não está aberto

104 - Ficheiro não está aberto para leitura

105 - Ficheiro não está aberto para escrita

106 - Número inválido

150 - Disco protegido contra escrita

151 - Dispositivo desconhecido

152 - A drive não está preparada

153 - Comando inválido

154 - Erro na verificação do CRC

155 - Drive inválida

156 - Erro de procura no disco

157 - Tipo de media inválido

158 - Sector não encontrado

159 - Impressora sem papel

160 - Erro ao escrever no dispositivo

161 - Erro ao ler do dispositivo

162 - Falha de hardware

O método de uso é claro à escolha do programador, mas uma boa opção é usar a estrutura Case... Of:

ErrCode:=IOResult;
case ErrCode of
   2: Writeln('O ficheiro não foi encontrado...');
   3: Writeln('O caminho não foi encontrado...');
   .
   .
   .
   162: Writeln('Falha de Hardware...');
else if ErrCode<>0 then writeln('Erro desconhecido. . .');
end;

"A humanidade está a perder os seus génios... Aristóteles morreu, Newton já lá está, Einstein finou-se, e eu hoje não me estou a sentir bem!"

> Não esclareço dúvidas por PM: Indica a tua dúvida no quadro correcto do forum.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.