How to open (read-write) or create a file with truncation allowed?
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()
Open file for reading and writing with truncate
If you want to store the data then truncate use r+
:
with open(PATH,"r+") as f:
line = f.read()
f.seek(0)
f.truncate()
Why truncate when we open a file in 'w' mode in python
It's redundant since, as you noticed, opening in write mode will overwrite the file. More information at Input and Output
section of Python documentation.
How to make open() truncate an existing file
Please add O_TRUNC flag and remove O_EXCL.
open(filename, O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
From open man page -
O_EXCL Ensure that this call creates the file: if this flag is
specified in conjunction with O_CREAT, and pathname already
exists, then open() will fail.
O_TRUNC
If the file already exists and is a regular file and the
access mode allows writing (i.e., is O_RDWR or O_WRONLY) it
will be truncated to length
How to open a file for reading and writing, create it if doesn't exist yet, and if it does, then without truncating it?
With a little low-level helper:
import os
def open_create(name, flags):
return os.open(name, flags | os.O_CREAT)
with open("./testfile", 'r+', opener=open_create) as f:
... read/write ...
Python: truncate txt file before writing
You could simply open
the output file earlier, in the first for
loop. E.g.
for index_out, output in enumerate(output_files):
with open(output, 'w') as o:
for index_in, file in enumerate(txt_files):
with open(file, 'r+') as f:
print('Writing input {} to output {}'.format(index_in, index_out))
o.write(f.read())
This will only open and truncate each output file once, before the second for
loop starts, and the file
object will look after the current position in the output file.
Open file for read/write, create if needed
You need to use os.open()
to open it at a lower level in the OS than open()
allows. In particular, passing os.RDWR | os.O_CREAT
as flags
should do what you want. See the open(2)
man page for details. You can then pass the returned FD to os.fdopen()
to get a file object from it.
open() in Python does not create a file if it doesn't exist
You should use open
with the w+
mode:
file = open('myfile.dat', 'w+')
Related Topics
Running a Bash Script from Python
Python Multiprocessing + Subprocess Issues
Importing Orange Returns "Importerror: No Module Named Orange"
Executable Python Program with All Dependencies for Linux
I Have a Problem with Sending Mail:Typeerror: _Init_() Got an Unexpected Keyword Argument 'Context'
Handling Spreadsheet Data Through the Clipboard in Gtk
Use Df Command to Show Only the %Used
Python3 Flask Asyncio Subprocess in Route Hangs
How to Run Celery Workers by Superuser
Ubuntu 'Failed to Import the Site Module' Error Message
Change Parent Shell's Environment from a Subprocess
Pytest - Specify Log Level from the Cli Command Running the Tests