Есть несколько проблем с вашим кодом, но что касается ошибки ввода-вывода, в частности, ошибка 6 означает «недопустимый дескриптор файла».
Поскольку вы получаете всплывающее уведомление об ошибке, у вас явно есть Проверка ввода-вывода включена, что по умолчанию.
Ошибка ввода-вывода 6 не характерна для сбоя на System.Reset()
, и вы не видите никаких ошибки другого типа, связанные с ошибкой при открытии файла, поэтому мы можем с уверенностью предположить, что файл открывается успешно и что System.Readln()
и System.CloseFile()
не выполняются передал недопустимый дескриптор ввода / вывода.
Таким образом, остается только одна строка, которая может получить недопустимый дескриптор ввода / вывода:
while not EOF do
System.Eof()
имеет необязательный параметр, который сообщает ему, какой файл проверять. Поскольку вы пропускаете этот параметр, Eof()
будет использовать System.Input
. И процесс GUI не имеет дескриптора STDIN, назначенного по умолчанию. Таким образом, вероятно, откуда исходит ошибка 6.
Эта строка должна быть заменена на эту:
while not EOF(tSongFile) do
UPDATE : учитывая объявление arrSongs
, которое вы указали в комментариях (arrSongs: array[1..MAX] of string;
), существуют дополнительные проблемы с вашим кодом. Вы должны убедиться, что чтение l oop не пытается сохранить в массиве более MAX
строк. Кроме того, ваше чтение l oop пытается сохранить строку с индексом 0, который не является допустимым индексом, так как массив начинается с индекса 1. Кроме того, Display()
пропускает последнюю строку в массив. Посмотрите, что происходит, когда вы опускаете важные детали?
Попробуйте вместо этого:
private
arrSongs: array[1..MAX] of string;
...
procedure TfrmSongs.Display;
var
i: Integer;
begin
redOutput.Clear;
redOutput.Lines.Add('The TOP 10');
for i := 1 to iCount do
begin
redOutput.Lines.Add(IntToStr(i) + arrSongs[i]);
end;
end;
procedure TfrmSongs.FormActivate(Sender: TObject);
var
tSongList: TextFile;
sSong: string;
begin
iCount := 0;
AssignFile(tSongList, ExtractFilePath(Application.ExeName) + 'Songs.txt');
Reset(tSongList);
try
while (not EOF(tSongList)) and (iCount < MAX) do
begin
Readln(tSongList, sSong);
arrSongs[1+iCount] := sSong;
Inc(iCount);
end;
finally
CloseFile(tSongList);
end;
Display;
end;
При этом я бы предложил полностью избавиться от показания l oop. Вместо этого можно использовать TStringList
:
uses
..., System.Classes;
...
private
lstSongs: TStringList;
...
procedure TfrmSongs.Display;
var
i: Integer;
begin
redOutput.Clear;
redOutput.Lines.Add('The TOP 10');
for i := 0 to lstSongs.Count-1 do
begin
redOutput.Lines.Add(IntToStr(i+1) + lstSongs[i]);
end;
end;
procedure TfrmSongs.FormCreate(Sender: TObject);
begin
lstSongs := TStringList.Create;
end;
procedure TfrmSongs.FormDestroy(Sender: TObject);
begin
lstSongs.Free;
end;
procedure TfrmSongs.FormActivate(Sender: TObject);
begin
lstSongs.LoadFromFile(ExtractFilePath(Application.ExeName) + 'Songs.txt');
Display;
end;
Или вместо него можно использовать TFile.ReadAllLines()
:
uses
..., System.IOUtils;
...
private
arrSongs: TStringDynArray;
...
procedure TfrmSongs.Display;
var
i: Integer;
begin
redOutput.Clear;
redOutput.Lines.Add('The TOP 10');
for i := 0 to High(arrSongs) do
begin
redOutput.Lines.Add(IntToStr(i+1) + arrSongs[i]);
end;
end;
procedure TfrmSongs.FormActivate(Sender: TObject);
begin
arrSongs := TFile.ReadAllLines(ExtractFilePath(Application.ExeName) + 'Songs.txt');
Display;
end;