'pppppppp'
>>> file = open('random.bin', 'rb') # binary mode works the same here
>>> file.seek(reclen * 2) # fetch record 3
>>> file.read(reclen) # returns byte strings
b'YYYYYYYY'
But unless your file’s content is always a simple unencoded text form like ASCII and
has no translated line-ends, text mode should not generally be used if you are going to
seek—line-ends may be translated on Windows and Unicode encodings may make
arbitrary transformations, both of which can make absolute seek offsets difficult to use.
In the following, for example, the positions of characters after the first non-ASCII no
longer match between the string in Python and its encoded representation on the file:
>>> data = 'sp\xe4m' # data to your script
>>> data, len(data) # 4 unicode chars, 1 nonascii
('späm', 4)
>>> data.encode('utf8'), len(data.encode('utf8')) # bytes written to file
(b'sp\xc3\xa4m', 5)
>>> f = open('test', mode='w+', encoding='utf8') # use text mode, encoded
>>> f.write(data)
>>> f.flush()
>>> f.seek(0); f.read(1) # ascii bytes work
's'
>>> f.seek(2); f.read(1) # as does 2-byte nonascii
'ä'
>>> data[3] # but offset 3 is not 'm'!
'm'
>>> f.seek(3); f.read(1)
UnicodeDecodeError: 'utf8' codec can't decode byte 0xa4 in position 0:
unexpected code byte
As you can see, Python’s file modes provide flexible file processing for programs that
require it. In fact, the os module offers even more file processing options, as the next
section describes.
Lower-Level File Tools in the os Module
The os module contains an additional set of file-processing functions that are distinct
from the built-in file object tools demonstrated in previous examples. For instance, here
is a partial list of os file-related calls:
os.open( path, flags, mode )
Opens a file and returns its descriptor
os.read( descriptor, N )
Reads at most N bytes and returns a byte string
os.write( descriptor, string )
Writes bytes in byte string string to the file
File Tools | 155