Вопрос

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

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

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

ПЕРЕРЕДАКТИРОВАТЬ:забудьте о правке

Это было полезно?

Решение

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

Другие советы

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

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

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

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

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

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

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top