2013-05-10 2 views
1

최근에 "너무 많은 파일 열기"에 대한 내 서버 예외가 있습니다. 나는 lsof를 확인했다. 그리고 물론, 같은 디렉토리에 열려있는 PDF 파일들이 많이있다. 이 특정 파일은 Django FileField를 통해 관리됩니다. 프로젝트에서 이름으로 파일을 명시 적으로 여는 모든 위치를 추적하려고했는데 찾을 수있는 위치는 하나 뿐이며 파일이 제대로 닫혀 있다고 말할 수 있습니다. 파일이 열려있는 다른 장소가있을 수 있지만 실제로 어떤 파일이 열려 있는지 확인하는 방법을 모릅니다. 나는 단순히 open()과 file()에 대한 호출을 위해 grepping을 시도했지만 운은 없다.파일을 열어 두는 코드 줄을 어떻게 알 수 있습니까?

파일을 열어 두어야하는 코드 줄을 체계적으로 추적 할 수있는 방법이 있습니까?

편집 : 제대로 파일을 열고 닫는 방법을 이해합니다. 내 질문은 파일을 열어두고 떠나는 코드의 기존 줄을 추적하는 방법이 있는지 여부입니다.

+0

'file.close()'호출이 결코 발생하지 않는 어딘가에 예외가 발생했을 가능성이 있습니다. 이것을 피하기 위해'try' /'finally'를 사용할 수는 있지만, [with' 문] (http://www.youtube.com/watch?v=lRaKmobSXF4)이 당신을 대신합니다. –

답변

4

open을 사용하는 경우 컨텍스트 관리자로 사용해보십시오. 당신이 그것을 완료하면 그 방법은, 무슨 일이 있더라도, 그것은 폐쇄하지됩니다 :

with open('file.txt', 'r') as fin: 
    # Access fin like normal 

# No matter what happens, after the block, it's closed! 

또는, 당신은 당신을 위해 몇 가지 추가 로깅을 자신의 기능을 openclose의 인스턴스를 대체 할 수 :

def my_open(filename, *args): 
    logger.debug('Opening %s' % filename) 
    return open(filename, *args) 

def my_close(file_obj): 
    logger.debug('Closing %s' % file_obj.name) 
    return file_obj.close() 

마지막 수단으로 문제의 코드에 액세스 할 수 없거나 코드를 변경하는 것이 번거롭다면 기능을 원숭이 패치 할 수 있습니다.

import traceback 
class MyFile(file): 
    @staticmethod 
    def open(*args, **kwargs): 
     return MyFile(*args, **kwargs) 

    def __init__(self, *args, **kwargs): 
     self._file = self._open(*args, **kwargs) 
     print('Opening %s from %s' % (
      self._file.name, ''.join(traceback.format_stack()))) 

    def close(self): 
     print('Closing file %s from %s' % (
      self._file.name, ''.join(traceback.format_stack()))) 
     self._file.close() 

# Now the monkey-patching 
file = MyFile 
MyFile._open = open 
open = MyFile.open 

o = open('hello', 'w+') 

그것은 확실히 세계에서 가장 예쁜 것은 아니지만, 당신은 원숭이 패치 수 있다면 당신은 적어도 레거시 코드를 처리 할 수있을 것입니다.

+0

새로운 코드를 작성할 때 파일을 제대로 열거 나 닫아야하는 방법을 알고 있지만 파일을 제대로 닫지 않은 기존 코드 행을 찾는 것이 좋습니다. –

+1

필자의 최신 편집에서 원숭이 패치'open'과'file'의 가능성을 제안합니다. 아마도 가장 매력적인 아이디어는 아니지만 추적하는 데 도움이 될 것입니다. –

+0

디버깅을위한 훌륭한 솔루션입니다. 감사 :) –

0

가비지 수집기에 따라 파일을 닫을 수 있습니까? I.E. 핸들은 범위를 벗어나 파일을 "닫은"경우에도 GC가 실행될 때까지 사라지지 않습니다. 객체 체인이 범위를 벗어나지 않으면 GC가이를 수집 할 수 없습니다. 또한 GC가 실행 기회를 얻지 못하면 GC도 수집되지 않습니다.

장기 실행 프로세스에서 동일한 문제가 발생하여 내 시스템을 다시 설계하여 "해결"하여 모든 파일 액세스가 하위 개체 내부에서 발생하도록했습니다. 해당 객체는 사용 완료 후 참조 체인에서 제거되거나 오류가 발생했습니다. 이렇게하면 GC가 핸들을 수집 할 수있었습니다.

관련 문제