下面列出了java.io.InputStream#mark ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
/**
* Makes sure that the header bytes are copied when creating a new buffer
* to hold all the required bytes when the stream has been marked.
* This will only happen the first time the buffer is filled, i.e. when the
* stream is marked before the first read (mark at position zero).
*
* @throws IOException if something goes wrong
*/
public void testHeaderPresentInStream_Internal()
throws IOException {
final int valueLen = DEFAULT_INTERNAL_BUFFER_SIZE + 5*1024;
InputStream is = getStream(valueLen);
is.mark(valueLen - 1024);
// Obtain a header generator to compare with.
ClobStreamHeaderGenerator hdrGen = new ClobStreamHeaderGenerator(false);
byte[] hdrTmp = new byte[100];
int headerLen = hdrGen.generateInto(hdrTmp, 0, valueLen);
byte[] hdr1 = new byte[headerLen];
System.arraycopy(hdrTmp, 0, hdr1, 0, headerLen);
byte[] hdr2 = new byte[headerLen];
// Get the first bytes from the stream being tested.
assertEquals(headerLen, is.read(hdr2));
assertEquals(new ByteArrayInputStream(hdr1),
new ByteArrayInputStream(hdr2));
}
/** Load lua source or lua binary from an input stream into a Prototype.
* The InputStream is either a binary lua chunk starting with the lua binary chunk signature,
* or a text input file. If it is a text input file, it is interpreted as a UTF-8 byte sequence.
* @param is Input stream containing a lua script or compiled lua"
* @param chunkname Name that will be used within the chunk as the source.
* @param mode String containing 'b' or 't' or both to control loading as binary or text or either.
*/
public Prototype loadPrototype(InputStream is, String chunkname, String mode) throws IOException {
if (mode.indexOf('b') >= 0) {
if (undumper == null)
error("No undumper.");
if (!is.markSupported())
is = new BufferedStream(is);
is.mark(4);
final Prototype p = undumper.undump(is, chunkname);
if (p != null)
return p;
is.reset();
}
if (mode.indexOf('t') >= 0) {
return compilePrototype(is, chunkname);
}
error("Failed to load prototype "+chunkname+" using mode '"+mode+"'");
return null;
}
private void testMarkAndReset(TransferKind transferKind) throws IOException {
MockResponse response = new MockResponse();
transferKind.setBody(response, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 1024);
server.enqueue(response);
server.enqueue(response);
server.play();
InputStream in = server.getUrl("/").openConnection().getInputStream();
assertFalse("This implementation claims to support mark().", in.markSupported());
in.mark(5);
assertEquals("ABCDE", readAscii(in, 5));
try {
in.reset();
fail();
} catch (IOException expected) {
}
assertEquals("FGHIJKLMNOPQRSTUVWXYZ", readAscii(in, Integer.MAX_VALUE));
assertContent("ABCDEFGHIJKLMNOPQRSTUVWXYZ", server.getUrl("/").openConnection());
}
private FeedReader createFeedReader(InputStream in) throws Exception {
in.mark(8);
byte [] b = new byte[2];
int numRead = readExact(in, b);
in.reset();
if (numRead != b.length) {
throw new IllegalArgumentException("Need to read " + b.length + " bytes to detect format. Got " + numRead + " bytes.");
}
if (b[0] == '[') {
return new JsonFeedReader(in, docTypeMgr);
} else if ((b[0] == 'V') && (b[1] == '1')) {
return new VespaV1FeedReader(in, docTypeMgr);
} else {
return new VespaXMLFeedReader(in, docTypeMgr);
}
}
/**
* XMLEntityManager cares about endian-ness, since it creates its own optimized
* readers. Since we're just using generic Java readers for now, we're not caring
* about endian-ness. If this changes, even more code needs to be copied from
* XMLEntity manager. -- PJM
*/
protected String getEncodingName(InputStream stream) throws IOException {
final byte[] b4 = new byte[4];
String encoding = null;
// this has the potential to throw an exception
// it will be fixed when we ensure the stream is rewindable (see note above)
stream.mark(4);
int count = stream.read(b4, 0, 4);
stream.reset();
if (count == 4) {
encoding = getEncodingName(b4);
}
return encoding;
}
public void testNewInput_skip() throws IOException {
InputStream input = stringUnderTest.newInput();
int stringSize = stringUnderTest.size();
int nearEndIndex = stringSize * 2 / 3;
long skipped1 = input.skip(nearEndIndex);
assertEquals("InputStream.skip()", skipped1, nearEndIndex);
assertEquals("InputStream.available()",
stringSize - skipped1, input.available());
assertTrue("InputStream.mark() is available", input.markSupported());
input.mark(0);
assertEquals("InputStream.skip(), read()",
stringUnderTest.byteAt(nearEndIndex) & 0xFF, input.read());
assertEquals("InputStream.available()",
stringSize - skipped1 - 1, input.available());
long skipped2 = input.skip(stringSize);
assertEquals("InputStream.skip() incomplete",
skipped2, stringSize - skipped1 - 1);
assertEquals("InputStream.skip(), no more input", 0, input.available());
assertEquals("InputStream.skip(), no more input", -1, input.read());
input.reset();
assertEquals("InputStream.reset() succeded",
stringSize - skipped1, input.available());
assertEquals("InputStream.reset(), read()",
stringUnderTest.byteAt(nearEndIndex) & 0xFF, input.read());
}
private SortedMap parseDictionary(InputStream is) throws IOException {
SortedMap<ByteBuffer, Object> map = new TreeMap<ByteBuffer, Object>(new DictionaryComparator());
is.mark(0);
int readChar = is.read();
while (readChar != 'e') {
if (readChar < 0) {
throw new IOException("Unexpected EOF found");
}
is.reset();
map.put(parseByteString(is), parse(is));
is.mark(0);
readChar = is.read();
}
return map;
}
public static final MidiEvent parseEvent(long tick, long delta, InputStream in) throws IOException
{
in.mark(1);
boolean reset = false;
int id = in.read();
if(!verifyIdentifier(id))
{
in.reset();
reset = true;
}
if(sType >= 0x8 && sType <= 0xE)
{
return ChannelEvent.parseChannelEvent(tick, delta, sType, sChannel, in);
}
else if(sId == 0xFF)
{
return MetaEvent.parseMetaEvent(tick, delta, in);
}
else if(sId == 0xF0 || sId == 0xF7)
{
VariableLengthInt size = new VariableLengthInt(in);
byte[] data = new byte[size.getValue()];
in.read(data);
return new SystemExclusiveEvent(sId, tick, delta, data);
}
else
{
System.out.println("Unable to handle status byte, skipping: " + sId);
if(reset)
{
in.read();
}
}
return null;
}
/**
* Tries to read a data model version using each VersionedSerializer, in descending version order.
* If no version could be read from any serializer, then a SerializationException is thrown.
*
* When deserializing, clients are expected to call this method to obtain the version, then call
* {@method isProcessGroupVersion}, which then determines if {@method deserializeProcessGroup}
* should be used, or if {@method deserializeFlowContent} should be used.
*
* @param input the input stream containing serialized flow content
* @return the data model version from the input stream
* @throws SerializationException if the data model version could not be read with any serializer
*/
public int readDataModelVersion(final InputStream input) throws SerializationException {
final InputStream markSupportedInput = input.markSupported() ? input : new BufferedInputStream(input);
// Mark the beginning of the stream.
markSupportedInput.mark(SerializationConstants.MAX_HEADER_BYTES);
// Try each serializer in descending version order
for (final int serializerVersion : descendingVersions) {
final VersionedSerializer<?> serializer = allSerializers.get(serializerVersion);
try {
return serializer.readDataModelVersion(markSupportedInput);
} catch (SerializationException e) {
if (logger.isDebugEnabled()) {
logger.error("Unable to read the data model version due to: {}", e.getMessage());
}
continue;
} finally {
// Reset the stream position.
try {
markSupportedInput.reset();
} catch (IOException resetException) {
// Should not happen.
logger.error("Unable to reset the input stream.", resetException);
}
}
}
throw new SerializationException("Unable to read the data model version for the flow content.");
}
public AudioFileFormat getAudioFileFormat(InputStream stream)
throws UnsupportedAudioFileException, IOException {
stream.mark(200);
AudioFileFormat format;
try {
format = internal_getAudioFileFormat(stream);
} finally {
stream.reset();
}
return format;
}
/**
* Tests an implementation specific feature of ReaderToUTF8Stream, which is
* that the mark isn't invalidated even though we read past the read ahead
* limit, given that the internal buffer doesn't have to be refilled.
* <p>
* <em>WARNING</em>:This implementation specific feature should not be
* relied on by the production code! It may change at any time.
*
* @throws IOException if something goes wrong
*/
public void testMarkResetExceedReadAheadLimitOK_Internal()
throws IOException {
InputStream is = getStream(4*1024+17);
is.mark(10);
assertEquals(20, is.read(new byte[20]));
// Note the following is implementation dependent.
// Since the bytes are already stored in the internal buffer, we won't
// fail the reset even though we have exceeded the read ahead limit.
// With a different stream implementation, this may fail!
is.reset();
}
/**
* Get the UTrie version from an InputStream containing the serialized form
* of either a Trie (version 1) or a Trie2 (version 2).
*
* @param is an InputStream containing the serialized form
* of a UTrie, version 1 or 2. The stream must support mark() and reset().
* The position of the input stream will be left unchanged.
* @param littleEndianOk If FALSE, only big-endian (Java native) serialized forms are recognized.
* If TRUE, little-endian serialized forms are recognized as well.
* @return the Trie version of the serialized form, or 0 if it is not
* recognized as a serialized UTrie
* @throws IOException on errors in reading from the input stream.
*/
public static int getVersion(InputStream is, boolean littleEndianOk) throws IOException {
if (! is.markSupported()) {
throw new IllegalArgumentException("Input stream must support mark().");
}
is.mark(4);
byte sig[] = new byte[4];
int read = is.read(sig);
is.reset();
if (read != sig.length) {
return 0;
}
if (sig[0]=='T' && sig[1]=='r' && sig[2]=='i' && sig[3]=='e') {
return 1;
}
if (sig[0]=='T' && sig[1]=='r' && sig[2]=='i' && sig[3]=='2') {
return 2;
}
if (littleEndianOk) {
if (sig[0]=='e' && sig[1]=='i' && sig[2]=='r' && sig[3]=='T') {
return 1;
}
if (sig[0]=='2' && sig[1]=='i' && sig[2]=='r' && sig[3]=='T') {
return 2;
}
}
return 0;
}
protected boolean isData(final InputStream in) throws IOException {
in.mark(1);
final int nextByte = in.read();
in.reset();
return nextByte > -1;
}
private static boolean isMoreData(final InputStream in) throws IOException {
in.mark(1);
final int nextByte = in.read();
if (nextByte == -1) {
return false;
}
in.reset();
return true;
}
public Soundbank getSoundbank(InputStream stream)
throws InvalidMidiDataException, IOException {
try {
stream.mark(512);
return new DLSSoundbank(stream);
} catch (RIFFInvalidFormatException e) {
stream.reset();
return null;
}
}
public Soundbank getSoundbank(InputStream stream)
throws InvalidMidiDataException, IOException {
try {
stream.mark(512);
return new SF2Soundbank(stream);
} catch (RIFFInvalidFormatException e) {
stream.reset();
return null;
}
}
public static AudioFileFormat getAudioFileFormat(InputStream is) throws
UnsupportedAudioFileException, IOException
{
try
{
//return AudioSystem.getAudioFileFormat(is);
throw new Exception();
}
catch (Exception iae)
{
if (DEBUG == true)
{
System.err.println("Using AppletVorbisSPIWorkaround to get codec");
}
try
{
// 2.2 Fix.
is.mark(4096);
//Class.forName("javazoom.spi.vorbis.sampled.file.VorbisAudioFileReader");
Class.forName("org.tritonus.sampled.file.jorbis.JorbisAudioFileReader");
//return new javazoom.spi.vorbis.sampled.file.VorbisAudioFileReader().
return new org.tritonus.sampled.file.jorbis.JorbisAudioFileReader().
getAudioFileFormat(is);
}
catch (ClassNotFoundException cnfe)
{
throw new IllegalArgumentException(
"Vorbis codec not properly installed");
}
}
// 2.2 Fix.
finally
{
is.reset();
}
}
@Override
public void readFrom(InputStream in) throws IOException {
// Skip data type byte (we assume it's already read)
size = 1;
InputStream markInputStream = in.markSupported() ? in : new BufferedInputStream(in);
while (true) {
// Look for the 3-byte object end marker [0x00 0x00 0x09]
markInputStream.mark(3);
byte[] endMarker = new byte[3];
markInputStream.read(endMarker);
if (endMarker[0] == OBJECT_END_MARKER[0]
&& endMarker[1] == OBJECT_END_MARKER[1]
&& endMarker[2] == OBJECT_END_MARKER[2]) {
// End marker found
size += 3;
return;
} else {
// End marker not found; reset the stream to the marked position and read an AMF property
markInputStream.reset();
// Read the property key...
String key = AmfString.readStringFrom(in, true);
size += AmfString.sizeOf(key, true);
// ...and the property value
AmfData value = AmfDecoder.readFrom(markInputStream);
size += value.getSize();
properties.put(key, value);
}
}
}
/**
*
* Determines the size of an input stream, and optionally calculates the MD5 hash for the stream.
*
* @param sourceStream
* A <code>InputStream</code> object that represents the stream to measure.
* @param writeLength
* The number of bytes to read from the stream.
* @param abandonLength
* The number of bytes to read before the analysis is abandoned. Set this value to <code>-1</code> to
* force the entire stream to be read. This parameter is provided to support upload thresholds.
* @param rewindSourceStream
* <code>true</code> if the stream should be rewound after it is read; otherwise, <code>false</code>.
* @param calculateMD5
* <code>true</code> if an MD5 hash will be calculated; otherwise, <code>false</code>.
*
* @return A {@link StreamMd5AndLength} object that contains the stream length, and optionally the MD5 hash.
*
* @throws IOException
* If an I/O error occurs.
* @throws StorageException
* If a storage service error occurred.
*/
public static StreamMd5AndLength analyzeStream(final InputStream sourceStream, long writeLength,
long abandonLength, final boolean rewindSourceStream, final boolean calculateMD5) throws IOException,
StorageException {
if (abandonLength < 0) {
abandonLength = Long.MAX_VALUE;
}
if (rewindSourceStream) {
if (!sourceStream.markSupported()) {
throw new IllegalArgumentException(SR.INPUT_STREAM_SHOULD_BE_MARKABLE);
}
sourceStream.mark(Constants.MAX_MARK_LENGTH);
}
MessageDigest digest = null;
if (calculateMD5) {
try {
digest = MessageDigest.getInstance("MD5");
}
catch (final NoSuchAlgorithmException e) {
// This wont happen, throw fatal.
throw Utility.generateNewUnexpectedStorageException(e);
}
}
if (writeLength < 0) {
writeLength = Long.MAX_VALUE;
}
final StreamMd5AndLength retVal = new StreamMd5AndLength();
int count = -1;
final byte[] retrievedBuff = new byte[Constants.BUFFER_COPY_LENGTH];
int nextCopy = (int) Math.min(retrievedBuff.length, writeLength - retVal.getLength());
count = sourceStream.read(retrievedBuff, 0, nextCopy);
while (nextCopy > 0 && count != -1) {
if (calculateMD5) {
digest.update(retrievedBuff, 0, count);
}
retVal.setLength(retVal.getLength() + count);
if (retVal.getLength() > abandonLength) {
// Abandon operation
retVal.setLength(-1);
retVal.setMd5(null);
break;
}
nextCopy = (int) Math.min(retrievedBuff.length, writeLength - retVal.getLength());
count = sourceStream.read(retrievedBuff, 0, nextCopy);
}
if (retVal.getLength() != -1 && calculateMD5) {
retVal.setMd5(Base64.encode(digest.digest()));
}
if (retVal.getLength() != -1 && writeLength > 0) {
retVal.setLength(Math.min(retVal.getLength(), writeLength));
}
if (rewindSourceStream) {
sourceStream.reset();
sourceStream.mark(Constants.MAX_MARK_LENGTH);
}
return retVal;
}
/**
* Uploads a blob in a single operation.
*
* @param sourceStream
* A <code>InputStream</code> object that represents the source stream to upload.
* @param length
* The length, in bytes, of the stream, or -1 if unknown.
* @param accessCondition
* An {@link AccessCondition} object that represents the access conditions for the blob.
* @param options
* A {@link BlobRequestOptions} object that specifies any additional options for the request. Specifying
* <code>null</code> will use the default request options from the associated service client (
* {@link CloudBlobClient}).
* @param opContext
* An {@link OperationContext} object that represents the context for the current operation. This object
* is used to track requests to the storage service, and to provide additional runtime information about
* the operation.
* @throws StorageException
* If a storage service error occurred.
*/
@DoesServiceRequest
protected final void uploadFullBlob(final InputStream sourceStream, final long length,
final AccessCondition accessCondition, final BlobRequestOptions options, final OperationContext opContext)
throws StorageException {
assertNoWriteOperationForSnapshot();
// Mark sourceStream for current position.
sourceStream.mark(Constants.MAX_MARK_LENGTH);
if (length < 0 || length > BlobConstants.MAX_SINGLE_UPLOAD_BLOB_SIZE_IN_BYTES) {
throw new IllegalArgumentException(String.format(SR.INVALID_STREAM_LENGTH,
BlobConstants.MAX_SINGLE_UPLOAD_BLOB_SIZE_IN_BYTES / Constants.MB));
}
ExecutionEngine.executeWithRetry(this.blobServiceClient, this,
uploadFullBlobImpl(sourceStream, length, accessCondition, options, opContext),
options.getRetryPolicyFactory(), opContext);
}