TStringlist无法迭代求助:CSV导入代码执行异常排查
CSV导入问题分析与修复
核心问题原因
1. 无法迭代多行的根本原因
- 你用
read(F, Datas)读取文件时,这个函数会在遇到第一个空白字符(空格、换行、制表符)时停止读取,所以只拿到了CSV第一行的第一个字段,而非整行数据。 - 后续的
st.CommaText和ExtractStrings都是基于这一小段字符串处理,导致ST里只有这一行的部分列数据,循环遍历的是这些列,根本没有多行数据可以迭代。
2. 触发I/O错误6的原因
- 你添加的
readln;没有指定文件变量,默认会读取控制台输入,但你的程序是GUI程序,没有关联有效的控制台输入句柄,因此触发了I/O错误6(无效的输入输出请求)。 - 就算改成
readln(F);,原代码也没有做循环读取每行的逻辑,依然无法遍历CSV的多行数据。
修正后的代码示例
procedure TOrder_import.Button1Click(Sender: TObject); var F: textfile; ST: TStringList; line: string; begin try ProgressBar1.Position := 0; ST := TStringList.Create; // 先判断用户是否选择了文件 if not order_entry.OpenDialog1.Execute then Exit; AssignFile(F, order_entry.OpenDialog1.FileName); Reset(F); try // 循环读取CSV的每一行 while not Eof(F) do begin Readln(F, line); // 读取整行数据 ST.Clear; // 处理新行前清空列表 ST.CommaText := line; // 自动分割CSV行(支持带引号的字段) // 判断字段数量足够,避免索引越界 if ST.Count > 88 then begin Memo1.Lines.Add(ST[4]); Memo1.Lines.Add(ST[12]); Memo1.Lines.Add(ST[22]); Memo1.Lines.Add(ST[46]); Memo1.Lines.Add(ST[57]); Memo1.Lines.Add(ST[60]); Memo1.Lines.Add(ST[62]); Memo1.Lines.Add(ST[72]); Memo1.Lines.Add(ST[88]); ProgressBar1.StepIt; end; end; finally CloseFile(F); // 必须关闭文件,避免句柄泄漏 end; ShowMessage('成功!!'); finally ST.Free; end; end;
额外注意事项
- 原代码遗漏了
CloseFile(F),会导致文件句柄泄漏,修正后已补充。 - 添加了文件选择判断,避免用户取消选择时程序出错。
- 增加字段数量校验,防止CSV行字段不足时触发索引越界错误。
ST.CommaText已经可以正确处理标准CSV格式(包括带引号的字段),不需要再调用ExtractStrings,两者同时使用会导致重复分割数据。
内容的提问来源于stack exchange,提问作者Error In Code
相关产品推荐
相关产品推荐

