📄 read.java
字号:
package com.mindprod.http;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.zip.GZIPInputStream;
/**
* Read from a server. See com.mindprod.submitter for sample code to use this class.
*
* @author Roedy Green, Canadian Mind Products
* @version 1.9 2008-08-22 support accept-charset, accept-encoding and accept-language. Fix bugs in gzip support.
*/
@SuppressWarnings( { "WeakerAccess" } )
public final class Read
{
// ------------------------------ FIELDS ------------------------------
/**
* characters should be arriving within a millisecond in ordinary circumstances. In order to avoid hogging at the
* CPU in a mad loop to read non-existence characters, we sleep and try again later. Time to sleep in ms.
*/
private static final int SLEEP_TIME = 100/* 0.1 sec = 100 ms */;
// -------------------------- PUBLIC STATIC METHODS --------------------------
/**
* Reads exactly len bytes from the input stream into the byte array. This method reads repeatedly from the
* underlying stream until all the bytes are read. InputStream.read is often documented to block like this, but in
* actuality it does not always do so, and returns early with just a few bytes. readBytesBlocking blocks until all
* the bytes are read, the end of the stream is detected, or an exception is thrown. You will always get as many
* bytes as you asked for unless you get an eof or other exception. Unlike readFully, you find out how many bytes
* you did get. Formerly called readBlocking.
*
* @param in stream to read
* @param b the buffer into which the data is read.
* @param off the start offset of the data in the array, not offset into the file!
* @param len the number of bytes to read.
* @param timeoutInMillis give up after this amount of time.
* @return number of bytes actually read.
* @throws IOException if an I/O error occurs, usually a timeout.
*/
@SuppressWarnings( { "NestedAssignment", "EmptyCatchBlock" } )
public static int readBytesBlocking( InputStream in,
byte b[],
int off,
int len,
int timeoutInMillis ) throws IOException
{
int totalBytesRead = 0;
int bytesRead;
long whenToGiveUp = System.currentTimeMillis() + timeoutInMillis;
while ( totalBytesRead < len
&& ( bytesRead =
in.read( b, off + totalBytesRead, len - totalBytesRead ) )
>= 0 )
{
if ( bytesRead == 0 )
{
try
{
if ( System.currentTimeMillis() >= whenToGiveUp )
{
throw new IOException( "timeout" );
}
// don't hammer the system and suck up all the CPU
// beating a tight loop when there are no chars.
// If this keeps up we may trigger a java.net.SocketTimeoutException exception.
Thread.sleep( SLEEP_TIME );
}
catch ( InterruptedException e )
{
}
}
else
{
totalBytesRead += bytesRead;
whenToGiveUp = System.currentTimeMillis() + timeoutInMillis;
}
}
return totalBytesRead;
}// end readBytesBlocking
/**
* Used to read until EOF on an InputStream that sometimes returns 0 bytes because data have not arrived yet. Does
* not close the stream. Formerly called readEverything.
*
* @param is InputStream to read from.
* @param estimatedLength Estimated number of <b>bytes</b> that will be read. -1 or 0 mean you have no idea. Best to
* make some sort of guess a little on the high side.
* @param timeoutInMillis give up after this amount of time.
* @param gzipped true if the bytes are compressed with gzip. Request decompression.
* @param encoding The encoding of the byte stream. readStringBlocking converts to a standard Unicode-16
* String. usually UTF-8 or ISO-8859-1.
* @return String representing the contents of the entire stream.
* @throws IOException if connection lost, timeout etc., possibly UnsupportedEncodingException If the named charset
* is not supported
*/
@SuppressWarnings( { "NestedAssignment", "EmptyCatchBlock" } )
public static String readStringBlocking( InputStream is,
int estimatedLength,
long timeoutInMillis,
boolean gzipped,
String encoding ) throws IOException
{
if ( estimatedLength <= 0 )
{
estimatedLength = 10 * 1024;
}
final int chunkSizeInBytes = Math.min( estimatedLength, 4 * 1024 );
final byte[] ba = new byte[chunkSizeInBytes];
// will grow as needed.
// O P E N
final ByteArrayOutputStream baos = new ByteArrayOutputStream( estimatedLength + 1024 );
final InputStream decoder;
if ( gzipped )
{
decoder = new GZIPInputStream( is, 4096/* buffsize in bytes */ );
}
else
{
decoder = is;
}
// -1 means eof, 0 means none available for now.
int bytesRead;
long whenToGiveUp = System.currentTimeMillis() + timeoutInMillis;
while ( ( bytesRead = decoder.read( ba, 0, chunkSizeInBytes ) ) >= 0 )
{
if ( bytesRead == 0 )
{
try
{
if ( System.currentTimeMillis() >= whenToGiveUp )
{
throw new IOException( "timeout" );
}
// no data for now
// wait a while before trying again to see if data has arrived.
// avoid hogging cpu in a tight loop
Thread.sleep( SLEEP_TIME );
}
catch ( InterruptedException e )
{
}
}
else
{
// got some data. Tack it on the end of our ByteArrayOutputStream
baos.write( ba, 0, bytesRead );
// start the timeout over, every time we get some data.
whenToGiveUp = System.currentTimeMillis() + timeoutInMillis;
}
}
// C L O S E
decoder.close();
baos.close();
return new String( baos.toByteArray(), encoding );
}// end readStringBlocking
// --------------------------- CONSTRUCTORS ---------------------------
/**
* Static only. Prevent instantiation.
*/
private Read()
{
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -