I am getting the following error when trying to output to a text file:
io.UnsupportedOperation: not writable.
My code:
def PostCodeStore(self):
#Opens the Postcode file in append mode
file = open("PostCode_File.txt", "r")
PostCodeValue= PostCodeVar.get()
#Writes the Postcode value to the file and adds a new line
file.write(PostCodeValue + "\n")
#Closes the file so it saves the value
file.close()
The reason is that you can't write to a file opened with 'r'. You must open with 'a'. From the documentation:
The first argument is a string containing the filename. The second argument is another string containing a few characters describing the way in which the file will be used. mode can be 'r' when the file will only be read, 'w' for only writing (an existing file with the same name will be erased), and 'a' opens the file for appending; any data written to the file is automatically added to the end. 'r+' opens the file for both reading and writing. The mode argument is optional; 'r' will be assumed if it’s omitted.
On Windows, 'b' appended to the mode opens the file in binary mode, so there are also modes like 'rb', 'wb', and 'r+b'. Python on Windows makes a distinction between text and binary files; the end-of-line characters in text files are automatically altered slightly when data is read or written. This behind-the-scenes modification to file data is fine for ASCII text files, but it’ll corrupt binary data like that in JPEG or EXE files. Be very careful to use binary mode when reading and writing such files. On Unix, it doesn’t hurt to append a 'b' to the mode, so you can use it platform-independently for all binary files.
This is a common issue, and (as seen in the docs), one that can cause some problems when writing cross-compatible programs, as Windows has a different set of permissions for binary files. You are likely not going to be working with binary files (maybe zipfiles), so I wouldn't worry about that too much. Just remember:
'w' # Writing
'r' # Reading (default)
'a' # Appending
'r+' # Read/Write
I believe I understand your problem correctly. That is, that your program wants to write many lines, one at a time (append). If you don't want to do that and just want a single entry in the file with a newline, you will want to use 'w'.
Also (and as a side note), Python class names generally start with a capital letter. That's why PostCodeValue shows up with different formatting. Conventionally, a variable like this should be named with small letters and underscores, such as post_code_value.
You're wrong
file = open("PostCode_File.txt", "r")#Opens the Postcode file in append mode
With r as mode, you open the file read-only, not append. That'd be a.
Related
Is there a way to stop Python rewriting files?
For example, when I run code once, it writes number "1" in text file. If I run same code tommorow, it won't erase that 1 from yesterday, it will add one more "1", so it should look like this:
1
1
My would look like this:
file = open("filename","w")
file.write(str(1) + "\n)
file.close()
If someone can tell me where is my mistake, please help me.
Thank you in advance !
If you read the docs for open, that second parameter that you're passing a "w" to is the mode:
mode is an optional string that specifies the mode in which the file is opened. It defaults to 'r' which means open for reading in text mode. Other common values are 'w' for writing (truncating the file if it already exists), 'x' for exclusive creation and 'a' for appending…
And then there's a handy chart of all of the mode characters, which reiterates the same information:
'w': open for writing, truncating the file first
...
'a': open for writing, appending to the end of the file if it exists
So, just use "a" instead of "w", and Python will add your new line to the end of the file, instead of truncating the file to nothing and then adding your new line to that now-empty file.
It's probably worth knowing that this is very closely based on the behavior of the fopen function from C and POSIX—which many other languages have also copied. So, in almost any language you run into, if there's a w mode for writing that overwrites the file, there's probably also an a mode for appending.
I am starting a module that opens a file, reads it, does some stuff, and then appends to it. However, I am trying to see what is in the file first. Here is the start of the program:
def addSkill(company):
with open("companies.txt", "a+") as companies:
for line in companies:
print('ok')
print(line.rstrip('\n'))
companies.write(company + '\r\n')
companies.close()
Neither of the print functions are working. There is text in the document. And it appends to it as requested. Any suggestions?
Just open using 'r+' then save in memories everything that you need, then it will automatically writing at the end. because your file descriptor will be at the end.
Opening files in 'a' automatically put your file descriptor at the end, therefore, your can't see what was written before that.
e.g
def addSkill(company):
with open('companies.txt', 'r+') as fd:
list_of_companies = fd.readlines()
fd.write(company + '\n')
list_of_companies.append(company) # adding the last company to the full list.
print('\n'.join(list_of_companies)) # print each company with a '\n'.
Bonus: your close() method is useless using with, python will do that for you.
In any cases, when you are unsure about the option of a function, please RTFM: open()
'r' open for reading (default)
'w' open for writing, truncating the file first
'x' open for exclusive creation, failing if the file already exists
'a' open for writing, appending to the end of the file if it exists
'b' binary mode
't' text mode (default)
'+' open a disk file for updating (reading and writing)
'U' universal newlines mode (deprecated)
I'm actually working on a project to send file using UDP, and since this protocol is not reliable I added some information on each packet which is the index of the data. So I can write the received data in the correct order.
I have problems to write bytes in a specific position in a file
this is the part of my code that handle writing new data :
while i < packet_num:
buf,address = recieve_packet(s,data_size+10)
i += 1
if buf:
print(buf)
index = int(buf[0:10].decode())
data = buf[10:]
f.seek(seek_pointer + index*data_size,0)
f.write(data)
list_index.append(index)
in this case the seek function has no effect and the data is just appended to the file. I'm using "a+b" mode to open the file.
Quoting from tutorialspoint.com,
Note that if the file is opened for appending using either 'a' or 'a+', any seek() operations will be undone at the next write.
"a" mode write operations append to the end of the file. What seek does is it sets the write/read pointer to a specific location in the file.
Therefore, when a write is called, it will write to the end of file, regardless of the read/write pointer.
However, because you've opened the file in a+b, you would be able to seek to a specific location and read it.
If you open using 'append' mode, all writes go to the end of the file. If ypu are already keeping track of where received data, then opening in w+b mode is all you need to do.
wb creates (or empties) the file, and allows writing (in binary, rather than text mode). w+b Does the same, but allows reading as well. If you want to open an existing file without truncating it, mode r+b will allow both reading and writing, while preserving the existing data (again, the b is for binary mode, which I expect is correct for your uses).
I know this is a simple question, but I am extremely stuck.
file=open("record.txt","w+")
record = file.read()
print("The record is "+str(record)+"!!")
main code...
file.write(str(reaction))
file.close()
I have got his code and I've got a number of 0.433534145355 in the file, but when I do the command of print the +str(record)+, it only comes up with The record is !! and the number is not there. What is wrong with this code. Is there a special code with decimal places, and I do not want to use int().
As it says here:
'w+' Open for reading and writing. The file is created if it does not
exist, otherwise it is truncated. The stream is positioned at
the beginning of the file.
so yes, your file is also opened for reading, but it is truncated (i.e. it is now zero bytes long, it's empty), leaving nothing left to read of what was there already.
Essentially, the w in 'w+' means the mode is orientated to writing, giving you the option to read as well (useful in those cases when you need to seek back and read what you have written. There will be nothing to read unless you write)
Instead you can use:
'r+' Open for reading and writing. The stream is positioned at the
beginning of the file.
In this case, the r in 'r+' signifies the mode is orientated to reading, giving you the option to seek and write where necessary (useful when data is present already, but might need to be changed)
If you want to read from a file, you have to open it for reading too (r).
I'm trying to input data from a csv and run that through a simple function and return it to the same CSV but appended onto the end of the row.
I'm having a hard time understanding the difference between the various modes(r, r+, a+, etc).
I've read the documentation but as a beginner am not understanding quite what they mean and which one is the right for me to be using in this case.
def appendCurrentTime():
with open("file.csv", "??") as myfile: #Opens File
reader = csv.reader(myfile)
for row in reader: #Runs through each row
myfile.write(current_time(row[1])) #appends the time, pulling in row[1] into current_time
**Also posting code for the first time, sorry if it doesn't come through clearly.
Looking at your code, the main problem is that the CSV file is not a "database", so you can't modify a row in the middle without corrupting the next row.
So, open the source file in "rb" mode and destination file in "wb" mode, and AFTER you processed the whole file - delete original and rename new file to the original name.
And, description for the cases you specified:
"r" - open text file for reading, starting from the beginning.
"r+" - open text file for reading and writing, starting from the beginning.
"a+" - create file if not exists; then open as a text file for reading and writing, starting from the end of file, plus you can only write to the end of the file.
In short, "R" means Read, "W" write, "+" - "and other way around", "B" - binary, absense of "B" means text. "A" differs from "W" in that "W" clears the file contents when you call open.
IMHO you should probably open files in binary mode most of the time, even if they are logically "text", to prevent unintended conversions of special characters (especially important with Unicode). So, I would recommend "wb" to "write new file", "rb" to "read existing" and "ab" to "append to existing file" e.g. a log file.
For even more information, read the documentation for the POSIX fopen function - Python tries to adhere to its semantics as much as possible, even on Windows systems.
Since it is a CSV file and implied text, the "rU" flag would be appropriate. The r flag means read and U is universal line terminator mode. This way it won't matter if the file is using Windows, Mac or Unix line terminators.
Also take a look into the Sniffer provided by the CSV library. It will automatically detect most dialects for you and can be passed into the reader function.
http://docs.python.org/2/library/csv.html#csv.Sniffer