I have this code snippet and I'm trying to seek backwards from the end of file using python:
f=open('D:\SGStat.txt','a');
f.seek(0,2)
f.seek(-3,2)
This throws the following exception while running:
f.seek(-3,2)
io.UnsupportedOperation: can't do nonzero end-relative seeks
Am i missing something here?
From the documentation for Python 3.2 and up:
In text files (those opened without a
bin the mode string), only seeks relative to the beginning of the file are allowed (the exception being seeking to the very file end withseek(0, 2)).
Therefore, you can change your program to read:
f = open('D:\SGStat.txt', 'ab')
f.seek(0, 2)
f.seek(-3, 2)
However, you should be aware that adding the b flag when you are reading or writing text can have unintended consequences (with multibyte encoding for example), and in fact changes the type of data read or written. For a more thorough discussion of the cause of the problem, and a solution that does not require adding the b flag, see another answer to this question.
The existing answers do answer the question, but provide no solution.
From readthedocs:
If the file is opened in text mode (without
b), only offsets returned bytell()are legal. Use of other offsets causes undefined behavior.
This is supported by the documentation, which says that:
In text files (those opened without a
bin the mode string), only seeks relative to the beginning of the file [os.SEEK_SET] are allowed...
This means if you have this code from old Python:
f.seek(-1, 1) # seek -1 from current position
it would look like this in Python 3:
f.seek(f.tell() - 1, os.SEEK_SET) # os.SEEK_SET == 0
Solution
Putting this information together we can achieve the goal of the OP:f.seek(0, os.SEEK_END) # seek to end of file; f.seek(0, 2) is legal
f.seek(f.tell() - 3, os.SEEK_SET) # go backwards 3 bytes
In order to use seek from current position and end you have to open the text file in binary mode. See this example where I have created a file "nums.txt" and have put "ABCDEFGHIJKLMNOPQRSTUVWXYZ" in the file. I read the letters of the string "PYTHON" from the file and display the same. See the code I've run in python 3.6 windows in anaconda 4.2
>>> file=open('nums.txt','rb')
>>> file.seek(15,0)
15
>>> file.read(1).decode('utf-8')
'P'
>>> file.seek(8,1)
24
>>> file.read(1).decode('utf-8')
'Y'
>>> file.seek(-7,2)
19
>>> file.read(1).decode('utf-8')
'T'
>>> file.seek(7,0)
7
>>> file.read(1).decode('utf-8')
'H'
>>> file.seek(6,1)
14
>>> file.read(1).decode('utf-8')
'O'
>>> file.seek(-2,1)
13
>>> file.read(1).decode('utf-8')
'N'
来源:https://stackoverflow.com/questions/21533391/seeking-from-end-of-file-throwing-unsupported-exception