打开的文件太多了

时间:2009-03-02 08:31:33

标签: delphi file file-io

从多个客户端线程重复执行此代码块一段时间后,我收到一条消息“Too many open files”的EInOutError:

var InputFile : Text;
...
Assign (InputFile, FileName);
Reset (InputFile)
try
  // do some stuff
finally
  CloseFile (InputFile);
end;

客户端线程数约为10,因此任何时候都只能打开10个文件。 Delphi是否有可能拒绝立即关闭文件?我能确保它吗?或者我在这里犯了错误?这是我打开文件的唯一地方,try..finally块应该保证打开的文件关闭,不应该吗?

REEDIT:忘记编辑

7 个答案:

答案 0 :(得分:4)

我只能建议您使用更“现代”的设施来处理文件。我不知道使用Windows API是否存在打开文件的限制,但我刚测试并且可以轻松地并行打开1000个流:

procedure TForm1.Button1Click(Sender: TObject);
var
  Strs: TList;
  i: integer;
begin
  Strs := TList.Create;
  try
    for i := 1 to 1000 do begin
      Strs.Add(TFileStream.Create('D:\foo.txt', fmOpenRead or fmShareDenyWrite));
    end;
  finally
    FreeObjectList(Strs);
  end;
end;

我从来没有理解为什么人们仍然在新代码中使用无类型文件而不是 TStream 及其后代。

编辑:在您的评论中,您写道您只想阅读纯文本文件 - 如果是这样,只需创建一个 TStringList 并使用其 LoadFromFile()< / em>方法。

答案 1 :(得分:1)

Delphi在CloseFile中立即关闭。您的示例代码似乎是正确的。

在try和finally之间再试一次。

答案 2 :(得分:1)

您没有在较旧的基于Windows 9x的计算机上运行此功能,是吗?如果是这样,您可能会遇到DOS文件句柄问题。

答案 3 :(得分:1)

这里有 IS 线程安全问题,虽然我看不出它是如何导致问题的。

问题是重置使用全局FileMode变量。

至于客户端线程 - 你确定它们没有在断开的连接上泄漏吗?

答案 4 :(得分:0)

在重置和关闭时放置一些调试输出可能很有用,这样您就可以看到每个线程打开文件的时间长度。

答案 5 :(得分:0)

你真的需要线程吗?听起来他们正在给你带来麻烦。没有它们,您的代码将更容易调试。

答案 6 :(得分:0)

此代码应该可以正常工作。没有与使用线程代码中的文件相关的已知问题(据我所知)。我们经常使用这些习语,一切正常。

我建议添加一些日志代码(在Assign和CloseFile之前)以查看是否执行了a)close并且b)你真的只有10个线程在运行。也许你的线程终止逻辑是错误的,而CloseFile永远不会执行。