Есть ли способ решить ошибку ввода-вывода 6 в Delphi? - PullRequest
0 голосов
/ 12 марта 2020
procedure TfrmSongs.Display;
var
  i: Integer;
begin
  redOutput.Clear;
  redOutput.Lines.Add('The TOP 10');
  for i := 1 to iCount-1 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);
  while not EOF do
  begin
    Readln(tSongList, sSong);
    arrSongs[iCount] := sSong;
    Inc(iCount);
  end;
  CloseFile(tSongList);
  Display;
end;

Я пытаюсь отобразить массив, который я пытался создать с помощью текстового файла в расширенном редактировании. Но каждый раз, когда я запускаю приложение, оно выдает ошибку 'I / O error 6', и ничего не отображается. Я не знаю, что-то с текстовым файлом или с процедурой отображения.

1 Ответ

5 голосов
/ 12 марта 2020

Есть несколько проблем с вашим кодом, но что касается ошибки ввода-вывода, в частности, ошибка 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;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...