Question

Je reçois une erreur EInOutError avec le message "Trop de fichiers ouverts" lors de l'exécution répétée de ce blocage de code à partir d'un certain nombre de threads client:

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

Le nombre de threads client est d'environ 10, de sorte que seuls 10 fichiers peuvent être ouverts à tout moment. Est-il possible que Delphi refuse de fermer les fichiers immédiatement? Puis-je m'assurer que c'est le cas? Ou est-ce que je fais une erreur ici? C’est le seul endroit où j’ouvre les fichiers et le blocage try..finally devrait garantir que les fichiers ouverts seront fermés, non?

REEDIT: oubliez l'édition

Était-ce utile?

La solution

Je ne peux que vous conseiller d’utiliser la méthode plus "moderne". facilités pour traiter les dossiers. Je ne sais pas s'il existe une limite de fichiers ouverts à l'aide de l'API Windows, mais je viens de tester et pourrais facilement ouvrir 1000 flux en parallèle:

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;

Je n'ai jamais compris pourquoi les gens utilisent encore des fichiers non typés au lieu de TStream et de ses descendants dans le nouveau code.

Modifier: dans votre commentaire, vous écrivez que vous ne voulez lire que les fichiers de texte brut. Si c'est le cas, créez simplement une TStringList et utilisez-la LoadFromFile () méthode.

Autres conseils

Vous n’exécutez pas cette opération sur un ancien ordinateur Windows 9x, n’est-ce pas? Si tel est le cas, vous rencontrez peut-être un problème de gestionnaire de fichiers DOS.

Delphi se ferme immidiatement dans le CloseFile. Votre exemple de code semble être correct.

Réessayez sans rien entre essayer et enfin.

Il EST un problème de sécurité des threads ici bien que je ne vois pas comment cela pourrait causer le problème.

Le problème est que Réinitialiser utilise la variable globale FileMode.

En ce qui concerne les threads clients, êtes-vous sûr qu'ils ne fuient pas en cas de connexion défectueuse ou autre chose?

Peut-être utile de mettre une sortie de débogage à côté de Reset et de Close afin que vous puissiez voir la durée pendant laquelle chaque fichier a ouvert le fichier.

Avez-vous vraiment besoin de threads? On dirait qu'ils vous causent des problèmes. Votre code serait plus facile à déboguer sans eux.

Ce code devrait fonctionner correctement. Il n'y a pas de problèmes connus liés à l'utilisation de fichiers à partir de code threadé (pour autant que je sache). Nous utilisons ces idiomes assez régulièrement et tout fonctionne bien.

Je suggérerais d'ajouter du code de journalisation (avant Assign et CloseFile) pour voir si a) close est exécuté et b) vous n'avez en réalité que 10 threads en cours d'exécution. Votre logique de terminaison de thread est peut-être défectueuse et CloseFile ne s'exécute jamais.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top