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 [EMAIL PROTECTED] 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; --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]