1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 package org.apache.pdfbox.io; 18 19 import java.io.InputStream; 20 import java.io.IOException; 21 22 /** 23 * This class allows a section of a RandomAccessFile to be accessed as an 24 * input stream. 25 * 26 * @author <a href="mailto:ben@benlitchfield.com">Ben Litchfield</a> 27 * @version $Revision: 1.5 $ 28 */ 29 public class RandomAccessFileInputStream extends InputStream 30 { 31 private RandomAccess file; 32 private long currentPosition; 33 private long endPosition; 34 35 /** 36 * Constructor. 37 * 38 * @param raFile The file to read the data from. 39 * @param startPosition The position in the file that this stream starts. 40 * @param length The length of the input stream. 41 */ 42 public RandomAccessFileInputStream( RandomAccess raFile, long startPosition, long length ) 43 { 44 file = raFile; 45 currentPosition = startPosition; 46 endPosition = currentPosition+length; 47 } 48 /** 49 * {@inheritDoc} 50 */ 51 public int available() 52 { 53 return (int)(endPosition - currentPosition); 54 } 55 /** 56 * {@inheritDoc} 57 */ 58 public void close() 59 { 60 //do nothing because we want to leave the random access file open. 61 } 62 /** 63 * {@inheritDoc} 64 */ 65 public int read() throws IOException 66 { 67 synchronized(file) 68 { 69 int retval = -1; 70 if( currentPosition < endPosition ) 71 { 72 file.seek( currentPosition ); 73 currentPosition++; 74 retval = file.read(); 75 } 76 return retval; 77 } 78 } 79 /** 80 * {@inheritDoc} 81 */ 82 public int read( byte[] b, int offset, int length ) throws IOException 83 { 84 //only allow a read of the amount available. 85 if( length > available() ) 86 { 87 length = available(); 88 } 89 int amountRead = -1; 90 //only read if there are bytes actually available, otherwise 91 //return -1 if the EOF has been reached. 92 if( available() > 0 ) 93 { 94 synchronized(file) 95 { 96 file.seek( currentPosition ); 97 amountRead = file.read( b, offset, length ); 98 } 99 } 100 //update the current cursor position. 101 if( amountRead > 0 ) 102 { 103 currentPosition += amountRead; 104 } 105 return amountRead; 106 } 107 108 /** 109 * {@inheritDoc} 110 */ 111 public long skip( long amountToSkip ) 112 { 113 long amountSkipped = Math.min( amountToSkip, available() ); 114 currentPosition+= amountSkipped; 115 return amountSkipped; 116 } 117 }