1
r"""File-like objects that read from or write to a string buffer.
3
This implements (nearly) all stdio methods.
5
f = StringIO() # ready for writing
6
f = StringIO(buf) # ready for reading
7
f.close() # explicitly release resources held
8
flag = f.isatty() # always false
9
pos = f.tell() # get current position
10
f.seek(pos) # set current position
11
f.seek(pos, mode) # mode 0: absolute; 1: relative; 2: relative to EOF
12
buf = f.read() # read until EOF
13
buf = f.read(n) # read up to n bytes
14
buf = f.readline() # read until end of line ('\n') or EOF
15
list = f.readlines()# list of f.readline() results until EOF
16
f.truncate([size]) # truncate file at to at most size (default: current pos)
17
f.write(buf) # write at current position
18
f.writelines(list) # for line in list: f.write(line)
19
f.getvalue() # return whole file's contents as a string
22
- Using a real file is often faster (but less convenient).
23
- There's also a much faster implementation in C, called cStringIO, but
24
it's not subclassable.
25
- fileno() is left unimplemented so that code which uses it triggers
27
- Seeking far beyond EOF and then writing will insert real null
28
bytes that occupy space in the buffer.
29
- There's a simple test set (see end of this file).
32
from errno import EINVAL
36
__all__ = ["StringIO"]
38
def _complain_ifclosed(closed):
40
raise ValueError, "I/O operation on closed file"
43
"""class StringIO([buffer])
45
When a StringIO object is created, it can be initialized to an existing
46
string by passing the string to the constructor. If no string is given,
47
the StringIO will start empty.
49
The StringIO object can accept either Unicode or 8-bit strings, but
50
mixing the two may take some care. If both are used, 8-bit strings that
51
cannot be interpreted as 7-bit ASCII (that use the 8th bit) will cause
52
a UnicodeError to be raised when getvalue() is called.
54
def __init__(self, buf = ''):
55
# Force self.buf to be a string or unicode
56
if not isinstance(buf, basestring):
69
"""A file object is its own iterator, for example iter(f) returns f
70
(unless f is closed). When a file is used as an iterator, typically
71
in a for loop (for example, for line in f: print line), the next()
72
method is called repeatedly. This method returns the next input line,
73
or raises StopIteration when EOF is hit.
83
"""Free the memory buffer.
87
del self.buf, self.pos
90
"""Returns False because StringIO objects are not connected to a
93
_complain_ifclosed(self.closed)
96
def seek(self, pos, mode = 0):
97
"""Set the file's current position.
99
The mode argument is optional and defaults to 0 (absolute file
100
positioning); other values are 1 (seek relative to the current
101
position) and 2 (seek relative to the file's end).
103
There is no return value.
105
_complain_ifclosed(self.closed)
107
self.buf += ''.join(self.buflist)
113
self.pos = max(0, pos)
116
"""Return the file's current position."""
117
_complain_ifclosed(self.closed)
120
def read(self, n = -1):
121
"""Read at most size bytes from the file
122
(less if the read hits EOF before obtaining size bytes).
124
If the size argument is negative or omitted, read all data until EOF
125
is reached. The bytes are returned as a string object. An empty
126
string is returned when EOF is encountered immediately.
128
_complain_ifclosed(self.closed)
130
self.buf += ''.join(self.buflist)
135
newpos = min(self.pos+n, self.len)
136
r = self.buf[self.pos:newpos]
140
def readline(self, length=None):
141
"""Read one entire line from the file.
143
A trailing newline character is kept in the string (but may be absent
144
when a file ends with an incomplete line). If the size argument is
145
present and non-negative, it is a maximum byte count (including the
146
trailing newline) and an incomplete line may be returned.
148
An empty string is returned only when EOF is encountered immediately.
150
Note: Unlike stdio's fgets(), the returned string contains null
151
characters ('\0') if they occurred in the input.
153
_complain_ifclosed(self.closed)
155
self.buf += ''.join(self.buflist)
157
i = self.buf.find('\n', self.pos)
162
if length is not None:
163
if self.pos + length < newpos:
164
newpos = self.pos + length
165
r = self.buf[self.pos:newpos]
169
def readlines(self, sizehint = 0):
170
"""Read until EOF using readline() and return a list containing the
173
If the optional sizehint argument is present, instead of reading up
174
to EOF, whole lines totalling approximately sizehint bytes (or more
175
to accommodate a final whole line).
179
line = self.readline()
183
if 0 < sizehint <= total:
185
line = self.readline()
188
def truncate(self, size=None):
189
"""Truncate the file's size.
191
If the optional size argument is present, the file is truncated to
192
(at most) that size. The size defaults to the current position.
193
The current file position is not changed unless the position
194
is beyond the new file size.
196
If the specified size exceeds the file's current size, the
197
file remains unchanged.
199
_complain_ifclosed(self.closed)
203
raise IOError(EINVAL, "Negative size not allowed")
204
elif size < self.pos:
206
self.buf = self.getvalue()[:size]
210
"""Write a string to the file.
212
There is no return value.
214
_complain_ifclosed(self.closed)
216
# Force s to be a string or unicode
217
if not isinstance(s, basestring):
222
self.buflist.append(s)
223
self.len = self.pos = spos + len(s)
226
self.buflist.append('\0'*(spos - slen))
228
newpos = spos + len(s)
231
self.buf += ''.join(self.buflist)
232
self.buflist = [self.buf[:spos], s, self.buf[newpos:]]
237
self.buflist.append(s)
242
def writelines(self, iterable):
243
"""Write a sequence of strings to the file. The sequence can be any
244
iterable object producing strings, typically a list of strings. There
247
(The name is intended to match readlines(); writelines() does not add
251
for line in iterable:
255
"""Flush the internal buffer
257
_complain_ifclosed(self.closed)
261
Retrieve the entire contents of the "file" at any time before
262
the StringIO object's close() method is called.
264
The StringIO object can accept either Unicode or 8-bit strings,
265
but mixing the two may take some care. If both are used, 8-bit
266
strings that cannot be interpreted as 7-bit ASCII (that use the
267
8th bit) will cause a UnicodeError to be raised when getvalue()
271
self.buf += ''.join(self.buflist)
276
# A little test suite
284
lines = open(file, 'r').readlines()
285
text = open(file, 'r').read()
287
for line in lines[:-2]:
289
f.writelines(lines[-2:])
290
if f.getvalue() != text:
291
raise RuntimeError, 'write failed'
293
print 'File length =', length
294
f.seek(len(lines[0]))
297
print 'First line =', repr(f.readline())
298
print 'Position =', f.tell()
300
print 'Second line =', repr(line)
301
f.seek(-len(line), 1)
302
line2 = f.read(len(line))
304
raise RuntimeError, 'bad result after seek back'
305
f.seek(len(line2), 1)
308
f.seek(f.tell() - len(line))
311
raise RuntimeError, 'bad result after seek back from EOF'
312
print 'Read', len(list), 'more lines'
313
print 'File length =', f.tell()
314
if f.tell() != length:
315
raise RuntimeError, 'bad length'
318
print 'Truncated length =', f.tell()
319
if f.tell() != length/2:
320
raise RuntimeError, 'truncate did not adjust length'
323
if __name__ == '__main__':