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__':