poi-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From bugzi...@apache.org
Subject DO NOT REPLY [Bug 13478] - [PATCH] [RFE] POIFS, RawDataBlock: Missing workaround for low performance InputStreams
Date Fri, 13 Jun 2003 20:30:21 GMT
DO NOT REPLY TO THIS EMAIL, BUT PLEASE POST YOUR BUG 
RELATED COMMENTS THROUGH THE WEB INTERFACE AVAILABLE AT
<http://nagoya.apache.org/bugzilla/show_bug.cgi?id=13478>.
ANY REPLY MADE TO THIS MESSAGE WILL NOT BE COLLECTED AND 
INSERTED IN THE BUG DATABASE.

http://nagoya.apache.org/bugzilla/show_bug.cgi?id=13478

[PATCH] [RFE] POIFS, RawDataBlock: Missing workaround for low performance InputStreams





------- Additional Comments From sys@yahoo.com  2003-06-13 20:30 -------
are you asking about BufferedInputStream or BlockingInputStream?

BufferedInputStream is not guaranteed to return enough bytes to fill your 
buffer so it will not return 512 bytes if you're using tcp/ip as input stream.
I've tried this, it doesnt work.


BlockingInputStream as proposed by Jens does not time out, and you yourself
(Andrew) agreed that it is undesirable for each user to have to wrap their 
input streams manually for RawDataBlock to work correctly. If that's required, 
then the changes should be made to RawDataBlock


Chris's proposal actually does not time out either, but it at least 
encapsulates the problem so that the end user will not have to wrap every 
input stream.

Time out is especially important for tcp/ip streams that may be lost.
If you look at my patch (it's above as a tar.bz2 attachment and also inlined 
below), my solution attempts to read until the desired 512 bytes is available, 
but if it finds zero data on over 100 consecutive reads, it gives up and 
returns so that the application will not be stalled.



inlined patch for my fix:




Index: RawDataBlock.java
===================================================================
RCS file: /home/cvspublic/jakarta-
poi/src/java/org/apache/poi/poifs/storage/RawDataBlock.java,v
retrieving revision 1.2
diff -u -r1.2 RawDataBlock.java
--- RawDataBlock.java	15 Mar 2002 02:47:56 -0000	1.2
+++ RawDataBlock.java	18 Mar 2003 19:16:04 -0000
@@ -62,18 +62,39 @@
 /**
  * A big block created from an InputStream, holding the raw data
  *
- * @author Marc Johnson (mjohnson at apache dot org
+ * @author Marc Johnson (mjohnson at apache dot org)
+ * @author Tony Chao (sys at yahoo dot com)
  */
 
 public class RawDataBlock
     implements ListManagedBlock
 {
+    /**
+     * Number of consecutive failed reads before giving up.
+     * (currently set to 5)
+     */
+    public static int  RETRY_COUNT = 5;
+
+    /**
+     * Number of milliseconds to sleep before retrying a failed read.
+     * (currently set to 100)
+     */
+    public static long RETRY_WAIT  = 100;
+    
     private byte[]  _data;
     private boolean _eof;
 
     /**
-     * Constructor RawDataBlock
-     *
+     * Constructor RawDataBlock.
+     * 
+     * Reads up to POIFSConstants.BIG_BLOCK_SIZE # of bytes and creates
+     * RawDataBlock from data read. If inputstream is not ready for read
+     * (e.g. read() returns 0), sleep briefly (RETRY_WAIT ms), and retry
+     * up to RETRY_COUNT consecutive times. This permits using various
+     * types of inputstreams (ServletInputStream, ByteArrayInputStream, etc)
+     * as input, but still exits gracefully (as opposed to waiting forever)
+     * if inputstream is unavailable.
+     * 
      * @param stream the InputStream from which the data will be read
      *
      * @exception IOException on I/O errors, and if an insufficient
@@ -84,8 +105,23 @@
         throws IOException
     {
         _data = new byte[ POIFSConstants.BIG_BLOCK_SIZE ];
-        int count = stream.read(_data);
+        int read = stream.read(_data);
+        int count = read;
+        int failcount = 0;
 
+        while (read >= 0 &&
+               count < POIFSConstants.BIG_BLOCK_SIZE &&
+               failcount < RETRY_COUNT)
+        {
+            read = stream.read(_data, count, _data.length-count);
+            count = (read >= 0) ? (count+read) : -1;
+            failcount = (read > 0) ? 0 : (failcount+1);
+            if (read==0) {
+                try {
+                    Thread.sleep(RETRY_WAIT);
+                } catch (InterruptedException e) {}
+            }
+        }
         if (count == -1)
         {
             _eof = true;

Mime
View raw message