69

私のアプリケーションには、以下の要求があります。 1. 1 つのスレッドが定期的にいくつかのログをファイルに記録します。ログ ファイルは一定の間隔でロールオーバーされます。ログファイルを小さく保つため。2. これらのログ ファイルを定期的に処理する別のスレッドもあります。例: ログ ファイルを別の場所に移動し、ログの内容を解析してログ レポートを生成します。

ただし、ログの記録に使用しているログ ファイルを 2 番目のスレッドが処理できないという条件があります。コード側では、擬似コードは次のようになります。

#code in second thread to process the log files
for logFile in os.listdir(logFolder):
     if not file_is_open(logFile) or file_is_use(logFile):
          ProcessLogFile(logFile) # move log file to other place, and generate log report....

では、ファイルが既に開いているか、他のプロセスで使用されているかを確認するにはどうすればよいですか? 私はインターネットでいくつかの研究をしました。そしていくつかの結果があります:

try:
   myfile = open(filename, "r+") # or "a+", whatever you need
except IOError:
    print "Could not open file! Please close Excel!"

このコードを試してみましたが、「r+」または「a+」フラグを使用しても機能しません

try:
   os.remove(filename) # try to remove it directly
except OSError as e:
    if e.errno == errno.ENOENT: # file doesn't exist
        break

このコードは機能しますが、ファイルが開いているかどうかを確認するためにファイルを削除したくないため、要求に到達できません。

4

7 に答える 7

56

ファイルが別のプロセスによって使用されているかどうかを確認しようとする際の問題は、競合状態の可能性です。ファイルをチェックして、それが使用されていないと判断すると、そのファイルを開く直前に、別のプロセス (またはスレッド) が飛び込んでファイルを取得 (または削除) する可能性があります。

わかりました、あなたがその可能性と一緒に暮らすことに決め、それが起こらないことを願っているとしましょう. 他のプロセスで使用中のファイルをチェックする方法は、オペレーティング システムによって異なります。

Linux では、/proc 内の PID を繰り返すだけで、かなり簡単です。特定の PID で使用中のファイルを反復処理するジェネレーターを次に示します。

def iterate_fds(pid):
    dir = '/proc/'+str(pid)+'/fd'
    if not os.access(dir,os.R_OK|os.X_OK): return

    for fds in os.listdir(dir):
        for fd in fds:
            full_name = os.path.join(dir, fd)
            try:
                file = os.readlink(full_name)
                if file == '/dev/null' or \
                  re.match(r'pipe:\[\d+\]',file) or \
                  re.match(r'socket:\[\d+\]',file):
                    file = None
            except OSError as err:
                if err.errno == 2:     
                    file = None
                else:
                    raise(err)

            yield (fd,file)

Windows ではそれほど単純ではなく、API は公開されていません。handle.exe使用できるsysinternals ツール ( ) がありますが、移植可能な PyPi モジュール をお勧めしますpsutil(つまり、Linux でも動作し、おそらく他の OS でも動作します)。

import psutil

for proc in psutil.process_iter():
    try:
        # this returns the list of opened files by the current process
        flist = proc.open_files()
        if flist:
            print(proc.pid,proc.name)
            for nt in flist:
                print("\t",nt.path)

    # This catches a race condition where a process ends
    # before we can examine its files    
    except psutil.NoSuchProcess as err:
        print("****",err) 
于 2012-06-20T08:23:44.207 に答える
3

inotifyを使用して、ファイル システムのアクティビティを監視できます。ロールオーバーが発生したことを示すファイル クローズ イベントを監視できます。また、ファイル サイズに関する条件を追加する必要があります。2 番目のスレッドからのファイル クローズ イベントを必ず除外してください。

于 2012-06-20T10:50:36.643 に答える