4

別のプロセスによって開いたままになっているログファイルを開いて、最初の数行を削除しようとしています。Unix では、単純に aos.open('/tmp/file.log', os.O_NONBLOCK)を実行するだけで、目標に近づくことができます。

今、私は Windows で立ち往生しており、ファイルを保持しているアプリケーションを終了せずに、このログを何らかの方法でローテーションする必要があります。これは可能ですか?

最初は、アプリケーションがログを想定している場所でファイル ハンドルを開き、Python でファイル ハンドルへのパイプとして機能することを検討しましたが、Windows でもそれを行う方法が見つかりませんでした。

また、ファイルを定期的に移動し、アプリケーションにファイルを再作成させることも考えましたが、別のプロセスで使用されているため、あまり効果がありません。

同様に考えO_SHLOCKましたが、それは Windows ではなく Unix です。だから私はファイルをmmapし、それがもう少し柔軟になることを願っていましたが、それは私をどこにも導きませんでした.

import mmap
import contextlib
import time

with open(r'test.log', 'r+') as f:
    with contextlib.closing(mmap.mmap(f.fileno(), 0)) as m:
        while 1:
            line = m.readline()
            if len(line) > 0:
                print line
            time.sleep(0.5)

これにより、Python がファイルを保持しているため、アプリケーションはファイルにアクセスできなくなります (逆も同様です)。

思いついたのですsignal.SIGHUPが、それもWindowsには存在しないので、振り出しに戻ります。

私は立ち往生していて、すべて試しました。Python はここで私を助けてくれますか、それとも言語を切り替える必要がありますか?

4

2 に答える 2

3

アプリケーションがファイルを共有オブジェクトとして開いたとしても、Python はそれができないので、見た目だけではうまくいきません。

それはそう悪くはありません :)。CreateFileアウグストが指摘したように、ファイルを開くことができます(する必要があります) 。これには標準のctypesモジュールを使用できます。Using a struct as a function argument with the python ctypes モジュールの質問では、その方法を確認できます。次に、C ランタイム ファイル記述子を、前の手順で取得した既存のオペレーティング システム ファイル ハンドルに関連付ける必要があります。_open_osfhandleこれを行うには、MS C ランタイム ライブラリ (CRT) から使用できます。ctypesを使用してもう一度呼び出すことができます。としてアクセスできますctypes.cdll.msvcrt._open_osfhandle。次に、Python ファイル オブジェクトを、前の手順で取得した既存の C ランタイム ファイル記述子に関連付ける必要があります。Python 3 でこれを行うには、組み込み関数の最初の引数としてファイル記述子を渡すだけです。open関数。ドキュメントによると

fileは、開くファイルのパス名 (絶対または現在の作業ディレクトリからの相対パス) を指定する文字列またはバイト オブジェクト、またはラップするファイルの整数ファイル記述子です

Python 2 ではos.fdopen、 ;を使用する必要があります。ドキュメントによると、そのタスクは

ファイル記述子 fd に接続された開いているファイル オブジェクトを返します。

このような単純なことを行うために、上記のすべてが必要なわけではありません。Windows での CPython の実装が、Windows プラットフォームの多くの機能へのアクセスを提供しない C ランタイム ライブラリを経由する代わりに、ネイティブの Windows API をファイルに使用し始めると、はるかに簡単になることが期待されます。詳細については、ネイティブ Windows API の問題を使用して新しい io.FileIO を追加するを参照してください。

于 2013-08-15T21:43:40.817 に答える
2

ログファイルを生成するアプリケーションを制御できますか? そのアプリケーションによってファイルが開かれる方法によっては、実際には変更できないためです。

このリンクはここではトピック外に見えるかもしれませんが、Windows の奥深くでは、他のアプリケーションへのファイル アクセスを決定するdwShareModeのは関数のパラメーターですCreateFile: http://msdn.microsoft.com/en-us/library/windows/desktop/aa363858 %28v=vs.85%29.aspx

アプリケーションは、ファイルをFILE_SHARE_WRITE書き込むFILE_SHARE_DELETEたびにファイル位置をフラッシュして更新する必要があります。の Pythonドキュメントを見ると、open()そのような詳細なパラメータはありません。

于 2013-08-13T15:11:31.960 に答える