W większości przypadków, gdy potrzebowałem otwierać dowolny plik stosowałem taką, lub podobną konstrukcję:
var
fInput: File of Byte;
wCount: Word;
begin
AssignFile(fInput, 'C:\File.dat');
try
Reset(fInput);
BlockRead(fInput, wCount, SizeOf(wCount));
finally
CloseFile(fInput);
end;
ReadLn;
end.
Co oczywiście wyklucza obsługę jakichkolwiek błędów podczas odczytu;
Załóżmy, że potrzebuję otworzyć plik, przy czym sprawdzić, czy faktycznie został otwarty, po czym jeśli operacja powiodła się rozpocząć wczytywanie danych; Jeżeli podczas odczytu danych wystąpi błąd to też go wychwycić; Po wszystkim plik zamknąć i gotowe; Błąd podczas odczytu może się zdarzyć jeśli plik będzie uszkodzony, np. zbyt krótki lub wczytywane dane będą nieprawidłowe, np. odczytuję datę, ale pobrany ciąg danych będzie uszkodzony czy przekłamany, czyli wartość dla daty będzie nieprawidłowa;
Na myśl przychodzi taka konstrukcja:
var
fInput: File of Byte;
wCount: Word;
begin
AssignFile(fInput, 'C:\File.dat');
try
try
Reset(fInput);
try
BlockRead(fInput, wCount, SizeOf(wCount));
except
on Exception do
WriteLn('Read Exception');
end;
finally
CloseFile(fInput);
end;
except
on Exception do
Write('Reset Exception.');
end;
ReadLn;
end.
i wszystko byłoby w porządku (bo jeśli plik nie istnieje bądź jest blokowany przez inny proces wyjątek zostanie poprawnie przechwycony), jednak żeby następnie przechwycić błąd podczas odczytu danych trzeba było dodać kolejny blok try .. except
pod Reset
, dzięki czemu tworzy się drabinka, choć taka konstrukcja nawet by mnie satysfakcjonowała, bo spełnia założenia;
Można także wykorzystać obsługę błdów I/O i odpowiednio sprawdzić IOResult
:
var
fInput: File of Byte;
wCount: Word;
begin
AssignFile(fInput, 'C:\File.dat');
{$I-}
Reset(fInput);
{$I+}
if IOResult = 0 then
try
try
BlockRead(fInput, wCount, SizeOf(wCount));
except
on Exception do
WriteLn('Read Exception');
end;
finally
CloseFile(fInput);
end
else
WriteLn('Reset Exception');
ReadLn;
end.
i też poprawnie zostaje obsłużony błąd otwarcia, a jeśli plik zostanie otwarty poprawnie ale odczyt danych się nie powiedzie - plik zostanie zamknięty a błąd wychwycony i wyświetlony komunikat Read Exception
; Taka kontrukcja też spełnia założenia, więc także można by ją wykorzystywać;
Sprawdzam różne konstrukcje i zamykanie pliku w tej sytuacji musi być wykonane jedynie wtedy, gdy IOResult = 0
, bo inaczej dostaję nieznany wyjątek programowy; To nie jest dziwne, bo zamkniętego pliku nie można zamknąć;
Moje pytanie brzmi: w jaki sposób poprawnie obsługiwać błędy związane z dostępem do pliku oraz odczytywaniem danych?
Nie potrzebuję rozróżniać nie wiadomo ile błędów, jedynie błąd otwarcia pliku i błąd odczytu danych z pliku; Z racji tej, że na razie nie mam jakiegoś super skutecznego sposobu chciałbym się dowiedzieć w jaki sposób Wy implementujecie obsługę błędów związanych z wczytywaniem danych z pliku; Proszę o przedstawienie Waszych metod, z których korzystacie na co dzień;