3

Is it possible to change file access mode after the file has been opened?

f=open(my_file, 'r')

change f to be able to write to it, or to declare that the file should be opened in universal newline mode?

Euphorbium
  • 1,177
  • 5
  • 17
  • 35

7 Answers7

9

Since changing file descriptor's permissions is not supported by Linux nor Windows. (there is no posix function to change open mode in linux at least), it's not possible to change it's permissions once the file descriptor have been set (Some OS specific tricks exists but I wouldn't recommend it).

You will need to reopen it with other permissions.

Community
  • 1
  • 1
aldeb
  • 6,588
  • 5
  • 25
  • 48
1

While there doesn't seem to be any way of changing the access mode on the underlying descriptor you could do the work somewhat at the python object level if you want to restrict the access (if you want to make a readonly file writable you're out of luck). Something like this:

f=open(my_file, 'w+')

f.write = None
f.writelines = None
# etc...

If you're using python2 you would need to wrap the file object to be able to disable the writing methods.

While you could restore a such modified file object to be writable again (and thereby you could circumvent the block - which by the way is almost always the case in python), it could be made to emulate the behaviour of a read-only file (which would be good enough for many cases).

skyking
  • 13,817
  • 1
  • 35
  • 57
  • This would only work in Python 3; `file.write` is a read-only attribute in Python 2. Also, this just creates an instance variable that shadows the class attribute; `type(f).write(f, ...)` would still be available. – chepner Oct 20 '17 at 21:22
  • @chepner You're probably right on python2 (which I updated the answer with). I was aware that you could circumvent such a block since you could restore the object. Very often techniques to disallow access in python can be circumvented - you must rely on the programmer to be sane enough not to do "stupid" things. – skyking Oct 23 '17 at 05:08
0

You can open file as follows to be able to read and write

f = open(my_file, 'r+')
Vader
  • 3,675
  • 23
  • 40
0

Assuming you've closed the file, just reassign to a new file object:

f = open(my_file, 'w')
Malik Brahimi
  • 16,341
  • 7
  • 39
  • 70
0

Given that you have a file object f_r that was opened only for reading, you can use os.fdopen() to get file object f_w that is associated with the same file, but has different mode:

f_r = open(filename, "r")
f_w = os.fdopen(f_read.fileno(), "a+")
f_w.write("Here I come\n")

However, this path can lead to misery and suffering when misused. Since file objects do some buffering (if not disabled), simultaneous use of both f_r and f_w can cause unexpected results. Also reopening <stdin> or <stdout> may or may not do what you need or expect.

wonder.mice
  • 7,227
  • 3
  • 36
  • 39
0

Here's how I solved this problem. For context, in my case, the file was only stored in memory, not on the disk, so I wasn't able to just reopen it from there.

from io import StringIO

...
bytes = file.read()
string = bytes.decode("utf-8") # or whatever encoding you wanna use
file = StringIO(string)
-1

If you do not want to reopen it, use:

f.mode = "mode-to-change-to"#w, a, r, ect.

for mode,

f.name = "file_name"

for name, and:

f.encoding = "encoding"#default is UTF-8

for encoding.


Edit


you should use:

with open("filename", "mode") as f:
    #do something
    f.mode = "another-mode"
    #do something else

so that the file closes automaticly when you are finished

Psychzander
  • 107
  • 14