有没有办法解决 Delphi 中的 I/O 错误 6?
Is there a way to solve an I/O error 6 in Delphi?
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' 错误并且没有任何显示。不知道是文本文件的问题还是显示程序的问题
您的代码存在一些问题,但具体针对 I/O 错误,错误 6 表示 "invalid file handle"。
由于您收到弹出式错误通知,显然您启用了 I/O checking,这是默认设置。
I/O 错误 6 不是典型的 System.Reset()
, and you are not seeing any other kind of error related to a failure in opening a file, so we can safely assume that the file is being opened successfully, and that System.Readln()
and System.CloseFile()
失败 未传递无效的 I/O 句柄。
因此只剩下一行可能接收到无效的 I/O 句柄:
while not EOF do
System.Eof()
has an optional parameter to tell it which file to check. Since you are omitting that parameter, Eof()
will use System.Input
代替。并且 GUI 进程没有默认分配的 STDIN 句柄。所以这很可能是错误 6 的来源。
该行需要改为:
while not EOF(tSongFile) do
UPDATE:鉴于您在评论 (arrSongs: array[1..MAX] of string;
) 中显示的 arrSongs
声明,您的代码还有其他问题。您需要确保读取循环不会尝试在数组中存储超过 MAX
个字符串。此外,您的阅读循环试图在索引 0 处存储一个字符串,这不是有效索引,因为数组从索引 1 开始。此外,Display()
正在跳过 last数组中的字符串。看看当您忽略重要细节时会发生什么?
试试这个:
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;
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' 错误并且没有任何显示。不知道是文本文件的问题还是显示程序的问题
您的代码存在一些问题,但具体针对 I/O 错误,错误 6 表示 "invalid file handle"。
由于您收到弹出式错误通知,显然您启用了 I/O checking,这是默认设置。
I/O 错误 6 不是典型的 System.Reset()
, and you are not seeing any other kind of error related to a failure in opening a file, so we can safely assume that the file is being opened successfully, and that System.Readln()
and System.CloseFile()
失败 未传递无效的 I/O 句柄。
因此只剩下一行可能接收到无效的 I/O 句柄:
while not EOF do
System.Eof()
has an optional parameter to tell it which file to check. Since you are omitting that parameter, Eof()
will use System.Input
代替。并且 GUI 进程没有默认分配的 STDIN 句柄。所以这很可能是错误 6 的来源。
该行需要改为:
while not EOF(tSongFile) do
UPDATE:鉴于您在评论 (arrSongs: array[1..MAX] of string;
) 中显示的 arrSongs
声明,您的代码还有其他问题。您需要确保读取循环不会尝试在数组中存储超过 MAX
个字符串。此外,您的阅读循环试图在索引 0 处存储一个字符串,这不是有效索引,因为数组从索引 1 开始。此外,Display()
正在跳过 last数组中的字符串。看看当您忽略重要细节时会发生什么?
试试这个:
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;