检查文件是否未打开或未被其他进程使用 [英] Check if a file is not open nor being used by another process

查看:29
本文介绍了检查文件是否未打开或未被其他进程使用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是我的申请,我有以下要求: 1.有一个线程会定期在文件中记录一些日志.日志文件将在一定间隔内翻转.用于保持日志文件较小. 2.还有另一个线程将定期处理这些日志文件.例如:将日志文件移到其他位置,解析日志内容以生成一些日志报告.

I my application, i have below requests: 1. There has one thread will regularly record some logs in file. The log file will be rollovered in certain interval. for keeping the log files small. 2. There has another thread also will regularly to process these log files. ex: Move the log files to other place, parse the log's content to generate some log reports.

但是,有一个条件是第二个线程无法处理用于记录日志的日志文件.在代码方面,伪代码类似于以下内容:

But, there has a condition is the second thread can not process the log file that's using to record the log. in code side, the pseudocode similars like below:

#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....

那么,我如何检查文件是否已打开或被其他进程使用? 我在互联网上做了一些研究.并得到一些结果:

So, how do i check is a file is already open or is used by other process? I did some research in internet. And have some results:

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

我尝试了这段代码,但是无论我使用"r +"还是"a +"标志,它都无法工作

I tried this code, but it doesn't work, no matter i use "r+" or "a+" flag

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

此代码可以工作,但无法达到我的要求,因为我不想删除该文件以检查它是否打开.

This code can work, but it can not reach my request, since i don't want to delete the file to check if it is open.

推荐答案

试图找出文件是否正在被另一个进程使用的问题是可能出现竞争状况.您可以检查一个文件,确定它未被使用,然后在打开它之前,另一个进程(或线程)会跳入并抓住它(甚至删除它).

An issue with trying to find out if a file is being used by another process is the possibility of a race condition. You could check a file, decide that it is not in use, then just before you open it another process (or thread) leaps in and grabs it (or even deletes it).

好,假设您决定忍受这种可能性,并希望这种可能性不会发生.检查其他进程正在使用的文件取决于操作系统.

Ok, let's say you decide to live with that possibility and hope it does not occur. To check files in use by other processes is operating system dependant.

在Linux上,这很简单,只需遍历/proc中的PID.这是一个生成器,用于迭代用于特定PID的文件:

On Linux it is fairly easy, just iterate through the PIDs in /proc. Here is a generator that iterates over files in use for a specific 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.有一个可以使用的sysinternals工具(handle.exe),但是我建议使用PyPi模块psutil,该模块是可移植的(即,它也可以在Linux上运行,并且可能在其他OS上运行):

On Windows it is not quite so straightforward, the APIs are not published. There is a sysinternals tool (handle.exe) that can be used, but I recommend the PyPi module psutil, which is portable (i.e., it runs on Linux as well, and probably on other 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) 

这篇关于检查文件是否未打开或未被其他进程使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆