How to open (read-write) or create a file with truncation allowed?

前端 未结 4 1623
無奈伤痛
無奈伤痛 2020-12-09 07:29

I want to:

  • open a file in read-write mode if it exists;
  • create it if it doesn\'t exist;
  • be able to truncate it anytime-anywhere.
4条回答
  •  春和景丽
    2020-12-09 08:18

    According to OpenGroup:

    O_TRUNC

    If the file exists and is a regular file, and the file is successfully opened O_RDWR or O_WRONLY, its length is truncated to 0 and the mode and owner are unchanged. It will have no effect on FIFO special files or terminal device files. Its effect on other file types is implementation-dependent. The result of using O_TRUNC with O_RDONLY is undefined.

    So, O_TRUNC is probably passed when opening a file with "w" or "w+". This gives "truncation" a different meaning, not what I want.

    With python the solution seems to open file at low-level I/O with os.open() function.

    The following python function:

    def touchopen(filename, *args, **kwargs):
        # Open the file in R/W and create if it doesn't exist. *Don't* pass O_TRUNC
        fd = os.open(filename, os.O_RDWR | os.O_CREAT)
    
        # Encapsulate the low-level file descriptor in a python file object
        return os.fdopen(fd, *args, **kwargs)
    

    has the behavior I wanted. You can use it like this (it's in fact my use case):

    # Open an existing file or create if it doesn't exist
    with touchopen("./tool.run", "r+") as doing_fd:
    
        # Acquire a non-blocking exclusive lock
        fcntl.lockf(doing_fd, fcntl.LOCK_EX)
    
        # Read a previous value if present
        previous_value = doing_fd.read()
        print previous_value 
    
        # Write the new value and truncate
        doing_fd.seek(0)
        doing_fd.write("new value")
        doing_fd.truncate()
    

提交回复
热议问题