Моя программа на python подготавливает входные данные, запускает внешний код FORTRAN и обрабатывает выходные данные в среде Windows HPC 2008. Он отлично работает, если код не выполняет внешнюю программу между 1042-1045 раз (обычно проблема сходится раньше).В этих ситуациях я получаю исключение:
WindowsError: [Ошибка 206] Имя файла или расширение слишком длинное
Однако путь к имени файла , а не растет со временем. Это просто очистка каталога и запуск снова.
Вот код:
inpF = open(inName)
outF = open(localOutName,'w')
p = subprocess.Popen(pathToExe,shell=False,stdin=inpF,stdout=outF,cwd=runPath)
stdout, stderr = p.communicate()
outF.close()
inpF.close()
pathToExe — это постоянная строка, указывающая на расположение в формате UNC (например, \\server\shared\program.exe), stdin — это открытый файл в режиме только для чтения на локальном диске, stdout — это открытый файл в режиме записи на локальном диске, а cwd — локальный путь на диске C:\. Я подтвердил, что ни один из аргументов подпроцесса не длиннее 80 символов, хотя ограничение должно быть 32 768, согласно этому несколько связанному сообщению .
Что я делаю не так? Каким-то образом накапливается что-то, что становится проблемой только тогда, когда я пробегаю больше тысячи раз.
ОБНОВЛЕНИЕ:
Чтобы проверить гипотезу о том, что открыто слишком много файлов, я сделал очень маленький пример, который очень быстро запускается с другим исполняемым файлом. Основное отличие здесь состоит в том, что stdin и stdout — это просто пустые файлы, тогда как в предыдущем случае они оба были большими файлами. В этом случае код отлично работает для 2000 запусков, тогда как более ранний терпит неудачу при ~ 1042. Так что дело не только в том, что файлов так много. Может быть, открыто слишком много больших файлов?
import subprocess
for i in range(nRuns):
if not (i % (nRuns/10.0)):
print('{0:.2}% complete'.format(i/float(nRuns)*100))
inpF=open('in.txt')
outF=open('out.txt','w')
p = subprocess.Popen('isotxsmerge.exe',shell=False,stdin=inpF,
stdout=outF,cwd='.')
stdout, stderr = p.communicate()
outF.close()
inpF.close()