[Python-checkins] cpython: Issue #12175: FileIO.readall() now only reads the file position and size once.

victor.stinner python-checkins at python.org
Thu May 26 00:22:47 CEST 2011


http://hg.python.org/cpython/rev/72c89daace57
changeset:   70390:72c89daace57
user:        Victor Stinner <victor.stinner at haypocalc.com>
date:        Thu May 26 00:16:44 2011 +0200
summary:
  Issue #12175: FileIO.readall() now only reads the file position and size once.

files:
  Misc/NEWS            |   5 +++-
  Modules/_io/fileio.c |  37 +++++++++++++++++++++++++------
  2 files changed, 34 insertions(+), 8 deletions(-)


diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -161,7 +161,10 @@
 Library
 -------
 
-- Issue #12180: Fixed a few remaining errors in test_packaging when no 
+- Issue #12175: FileIO.readall() now only reads the file position and size
+  once.
+
+- Issue #12180: Fixed a few remaining errors in test_packaging when no
   threading.
 
 - Issue #12175: RawIOBase.readall() now returns None if read() returns None.
diff --git a/Modules/_io/fileio.c b/Modules/_io/fileio.c
--- a/Modules/_io/fileio.c
+++ b/Modules/_io/fileio.c
@@ -547,14 +547,14 @@
 }
 
 static size_t
-new_buffersize(fileio *self, size_t currentsize)
+new_buffersize(fileio *self, size_t currentsize
+#ifdef HAVE_FSTAT
+               , off_t pos, off_t end
+#endif
+               )
 {
 #ifdef HAVE_FSTAT
-    off_t pos, end;
-    struct stat st;
-    if (fstat(self->fd, &st) == 0) {
-        end = st.st_size;
-        pos = lseek(self->fd, 0L, SEEK_CUR);
+    if (end != (off_t)-1) {
         /* Files claiming a size smaller than SMALLCHUNK may
            actually be streaming pseudo-files. In this case, we
            apply the more aggressive algorithm below.
@@ -579,9 +579,14 @@
 static PyObject *
 fileio_readall(fileio *self)
 {
+#ifdef HAVE_FSTAT
+    struct stat st;
+    off_t pos, end;
+#endif
     PyObject *result;
     Py_ssize_t total = 0;
     int n;
+    size_t newsize;
 
     if (self->fd < 0)
         return err_closed();
@@ -592,8 +597,23 @@
     if (result == NULL)
         return NULL;
 
+#ifdef HAVE_FSTAT
+#if defined(MS_WIN64) || defined(MS_WINDOWS)
+    pos = _lseeki64(self->fd, 0L, SEEK_CUR);
+#else
+    pos = lseek(self->fd, 0L, SEEK_CUR);
+#endif
+    if (fstat(self->fd, &st) == 0)
+        end = st.st_size;
+    else
+        end = (off_t)-1;
+#endif
     while (1) {
-        size_t newsize = new_buffersize(self, total);
+#ifdef HAVE_FSTAT
+        newsize = new_buffersize(self, total, pos, end);
+#else
+        newsize = new_buffersize(self, total);
+#endif
         if (newsize > PY_SSIZE_T_MAX || newsize <= 0) {
             PyErr_SetString(PyExc_OverflowError,
                 "unbounded read returned more bytes "
@@ -632,6 +652,9 @@
             return NULL;
         }
         total += n;
+#ifdef HAVE_FSTAT
+        pos += n;
+#endif
     }
 
     if (PyBytes_GET_SIZE(result) > total) {

-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list