Skip to content

Commit 7bba829

Browse files
committed
Added files.copyfileobj() as an alternative to shutil.copyfileobj() that supports a limit
1 parent dfc5293 commit 7bba829

1 file changed

Lines changed: 40 additions & 1 deletion

File tree

src/bd2k/util/files.py

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,47 @@ def rm_f( path ):
2828
raise
2929

3030

31-
if False:
31+
def copyfileobj( src, dst, limit=None, bufsize=1024 * 1024 ):
32+
"""
33+
Copy the contents of one file object to another file object. If limit is given, stop after at
34+
most limit bytes were copied. The copying will begin at the current file pointer of each file
35+
object.
36+
37+
:param src: the file object to copy from
38+
39+
:param dst: the file object to copy to
40+
41+
:param limit: the maximum number of bytes to copy or None if all remaining bytes in src
42+
should be copied
43+
44+
:param bufsize: the size of the intermediate copy buffer. No more than that many bytes will
45+
ever be read from src or written to dst at any one time.
3246
47+
:return: None if limit is None, otherwise the difference between limit and the number of
48+
bytes actually copied. This will be > 0 if and only if the source file hit EOF before limit
49+
number of bytes could be read.
50+
51+
>>> import tempfile
52+
>>> with open('/dev/urandom') as f1:
53+
... with tempfile.TemporaryFile() as f2:
54+
... copyfileobj(f1,f2,limit=100)
55+
... f2.seek(60)
56+
... with tempfile.TemporaryFile() as f3:
57+
... copyfileobj(f2,f3), f2.tell(), f3.tell()
58+
(None, 100, 40)
59+
"""
60+
while limit is None or limit > 0:
61+
buf = src.read( bufsize if limit is None or bufsize < limit else limit )
62+
if buf:
63+
if limit is not None:
64+
limit -= len( buf )
65+
assert limit >= 0
66+
dst.write( buf )
67+
else:
68+
return limit
69+
70+
71+
if False:
3372
# These are not needed for Python 2.7 as Python's builtin file object's read() and write()
3473
# method are greedy. For Python 3.x these may be useful.
3574

0 commit comments

Comments
 (0)