有没有办法解决Delphi中的I/O错误6


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错误6"错误,并且什么都不显示。我不知道是与文本文件有关,还是与显示过程有关。

您的代码有一些问题,但具体来说,关于I/O错误,错误6意味着"无效文件句柄"。

由于您收到弹出错误通知,您显然已启用I/O检查,这是默认情况。

I/O错误6不是System.Reset()上失败的典型错误,并且您没有看到任何其他类型的与打开文件失败相关的错误,因此我们可以放心地假设文件正在成功打开,并且System.Readln()System.CloseFile()没有被传递无效的I/O句柄。

因此,只剩下一行可能接收到无效的I/O句柄:

while not EOF do

System.Eof()有一个可选参数来告诉它要检查哪个文件。由于省略了该参数,Eof()将使用System.Input。默认情况下,GUI进程没有分配STDIN句柄。所以这很可能就是错误6的来源。

该行需要改为:

while not EOF(tSongFile) do

UPDATE:考虑到您在注释(arrSongs: array[1..MAX] of string;(中显示的arrSongs声明,您的代码还有其他问题。您需要确保读取循环不会尝试在数组中存储超过MAX的字符串。此外,您的读取循环正试图将字符串存储在索引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;

话虽如此,我还是建议彻底摆脱阅读循环。您可以使用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;

相关内容

最新更新