Слишком много открытых файлов - PullRequest
0 голосов
/ 02 марта 2009

Я получаю EInOutError с сообщением «Слишком много открытых файлов» при повторном выполнении этого блока кода в течение некоторого времени из ряда клиентских потоков:

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

Количество клиентских потоков составляет приблизительно 10, поэтому только 10 файлов могут быть открыты в любое время. Есть ли вероятность, что Delphi отказывается закрывать файлы сразу? Могу ли я убедиться в этом? Или я здесь ошибаюсь? Это единственное место, где я открываю файлы, и блок try..finally должен гарантировать закрытие открытых файлов, не так ли?

REEDIT: забудьте о редактировании

Ответы [ 7 ]

4 голосов
/ 02 марта 2009

Я могу только посоветовать вам использовать более «современные» средства для работы с файлами. Я не знаю, существует ли ограничение количества открытых файлов с помощью 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 () способ.

1 голос
/ 03 марта 2009

Там IS проблема безопасности потока здесь, хотя я не вижу, как это могло вызвать проблему.

Проблема в том, что Reset использует глобальную переменную FileMode.

Что касается клиентских потоков - вы уверены, что они не просачиваются при разрыве соединений или что-то в этом роде?

1 голос
/ 02 марта 2009

Вы не используете это на старом компьютере под управлением Windows 9x, не так ли? Если это так, вы можете столкнуться с проблемой дескриптора файла DOS.

1 голос
/ 02 марта 2009

Delphi немедленно закрывается в CloseFile. Ваш пример кода кажется правильным.

Попробуй еще раз без чего-либо между попыткой и наконец

0 голосов
/ 02 марта 2009

Этот код должен работать просто отлично. Нет известных проблем, связанных с использованием файлов из многопоточного кода (насколько я знаю). Мы используем такие идиомы довольно регулярно, и все работает нормально.

Я бы предложил добавить некоторый код регистрации (перед Assign и CloseFile), чтобы увидеть, выполняется ли a) close и b) у вас действительно работает только 10 потоков. Возможно, логика завершения потока неисправна, и CloseFile никогда не выполняется.

0 голосов
/ 02 марта 2009

Вам действительно нужны темы? Похоже, они вызывают у вас проблемы. Ваш код будет легче отлаживать без них.

0 голосов
/ 02 марта 2009

Может быть полезно поместить некоторые выходные данные отладки рядом с Reset и Close, чтобы вы могли видеть, как долго каждый поток имеет открытый файл.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...