Delphi 11.3 CE点击OpenDialog的Cancel触发I/O Error 6的原因与解决
Delphi 11.3 CE中OpenDialog点击Cancel触发I/O Error 6的原因及修复方案
问题原因
- 未检查
OpenDialog1.Execute()的返回值:当用户点击Cancel时,Execute()返回False,但原代码依然执行后续文件操作。此时OpenDialog1.FileName是空字符串,调用AssignFile(opfile, FileName)会生成无效文件句柄,后续Reset(opfile)就会抛出I/O Error 6(无效句柄)。 - 附带隐患:原代码中SaveDialog部分同样未检查
Execute()返回值,用户Cancel保存操作时也会触发同类错误。
修复方案
核心逻辑是先判断对话框的执行结果,仅当用户点击OK(Execute()返回True)时,才继续后续文件操作。修改后的代码如下:
procedure TForm1.Button3Click(Sender: TObject); begin // 处理保存逻辑 if not state then begin if not statef then begin // 确认用户点击保存对话框的OK if SaveDialog1.Execute() then begin FileName := SaveDialog1.FileName; AssignFile(opfile, FileName); try Rewrite(opfile); texty := Memo1.Text; Write(opfile, texty); finally CloseFile(opfile); // 确保文件无论如何都会关闭 end; state := true; end else begin // 用户取消保存,直接退出流程 Exit; end; end else begin // 已有打开的文件,直接保存 AssignFile(opfile, FileName); try Rewrite(opfile); texty := Memo1.Text; Write(opfile, texty); finally CloseFile(opfile); end; state := true; end; end; // 处理打开文件逻辑 Memo1.Text := ''; // 确认用户点击打开对话框的OK if OpenDialog1.Execute() then begin FileName := OpenDialog1.FileName; AssignFile(opfile, FileName); try Reset(opfile); Memo1.Clear; while not Eof(opfile) do begin Readln(opfile, texty); Memo1.Lines.Add(texty); end; finally CloseFile(opfile); // 避免文件资源泄漏 end; state := true; statef := true; end; // 用户取消打开操作,直接结束流程 end;
额外优化建议
- 用
try...finally包裹所有文件操作:确保即使发生异常,文件也能被正确关闭,防止资源泄漏。 - 提取重复代码:将保存文件的逻辑单独封装成函数,提升代码的可读性和可维护性。
内容的提问来源于stack exchange,提问作者Dotncom
相关产品推荐
相关产品推荐

