I am really confused when to use os.open
and when to use os.fdopen
I was doing all my work with os.open
and it worked without any
You are confusing the built-in open()
function with os.open()
provided by the os
module. They are quite different; os.open(filename, "w")
is not valid Python (os.open
accepts integer flags as its second argument), open(filename, "w")
is.
In short, open()
creates new file objects, os.open()
creates OS-level file descriptors, and os.fdopen()
creates a file object out of a file descriptor.
File descriptors are a low-level facility for working with files directly provided by the operating system kernel. A file descriptor is a small integer that identifies the open file in a table of open files kept by the kernel for each process. A number of system calls accept file descriptors, but they are not convenient to work with, typically requiring fixed-width buffers, multiple retries in certain conditions, and manual error handling.
File objects are Python classes that wrap file descriptors to make working with files more convenient and less error-prone. They provide, for example, error-handling, buffering, line-by-line reading, charset conversions, and are closed when garbage collected.
To recapitulate:
Built-in open()
takes a file name and returns a new Python file object. This is what you need in the majority of cases.
os.open()
takes a file name and returns a new file descriptor. This file descriptor can be passed to other low-level functions, such as os.read()
and os.write()
, or to os.fdopen()
, as described below. You only need this when writing code that depends on operating-system-dependent APIs, such as using the O_EXCL
flag to open(2)
.
os.fdopen()
takes an existing file descriptor — typically produced by Unix system calls such as pipe()
or dup()
, and builds a Python file object around it. Effectively it converts a file descriptor to a full file object, which is useful when interfacing with C code or with APIs that only create low-level file descriptors.
Built-in open
can be implemented using os.open()
(to create a file descriptor) and os.fdopen()
(to wrap it in a file object):
# equivalent to open(filename, "r")
f = os.fdopen(os.open(filename, os.O_RDONLY))