1 /************************************************************************ 2 * Copyright (c) 2000-2006 The Apache Software Foundation. * 3 * All rights reserved. * 4 * ------------------------------------------------------------------- * 5 * Licensed under the Apache License, Version 2.0 (the "License"); you * 6 * may not use this file except in compliance with the License. You * 7 * 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 * 14 * implied. See the License for the specific language governing * 15 * permissions and limitations under the License. * 16 ***********************************************************************/ 17 18 package org.apache.james.util.io; 19 20 import java.io.BufferedInputStream; 21 import java.io.File; 22 import java.io.FileInputStream; 23 import java.io.IOException; 24 import java.io.InputStream; 25 26 /*** 27 * @author Federico Barbieri <fede@apache.org> 28 */ 29 public class ResettableFileInputStream 30 extends InputStream 31 { 32 protected static final int DEFAULT_BUFFER_SIZE = 1024; 33 34 protected final String m_filename; 35 protected int m_bufferSize; 36 protected InputStream m_inputStream; 37 protected long m_position; 38 protected long m_mark; 39 protected boolean m_isMarkSet; 40 41 public ResettableFileInputStream( final File file ) 42 throws IOException 43 { 44 this( file.getCanonicalPath() ); 45 } 46 47 public ResettableFileInputStream( final String filename ) 48 throws IOException 49 { 50 this( filename, DEFAULT_BUFFER_SIZE ); 51 } 52 53 public ResettableFileInputStream( final String filename, final int bufferSize ) 54 throws IOException 55 { 56 m_bufferSize = bufferSize; 57 m_filename = filename; 58 m_position = 0; 59 60 m_inputStream = newStream(); 61 } 62 63 public void mark( final int readLimit ) 64 { 65 m_isMarkSet = true; 66 m_mark = m_position; 67 m_inputStream.mark( readLimit ); 68 } 69 70 public boolean markSupported() 71 { 72 return true; 73 } 74 75 public void reset() 76 throws IOException 77 { 78 if( !m_isMarkSet ) 79 { 80 throw new IOException( "Unmarked Stream" ); 81 } 82 try 83 { 84 m_inputStream.reset(); 85 } 86 catch( final IOException ioe ) 87 { 88 try 89 { 90 m_inputStream.close(); 91 m_inputStream = newStream(); 92 m_inputStream.skip( m_mark ); 93 m_position = m_mark; 94 } 95 catch( final Exception e ) 96 { 97 throw new IOException( "Cannot reset current Stream: " + e.getMessage() ); 98 } 99 } 100 } 101 102 protected InputStream newStream() 103 throws IOException 104 { 105 return new BufferedInputStream( new FileInputStream( m_filename ), m_bufferSize ); 106 } 107 108 public int available() 109 throws IOException 110 { 111 return m_inputStream.available(); 112 } 113 114 public void close() throws IOException 115 { 116 m_inputStream.close(); 117 } 118 119 public int read() throws IOException 120 { 121 m_position++; 122 return m_inputStream.read(); 123 } 124 125 public int read( final byte[] bytes, final int offset, final int length ) 126 throws IOException 127 { 128 final int count = m_inputStream.read( bytes, offset, length ); 129 m_position += count; 130 return count; 131 } 132 133 public long skip( final long count ) 134 throws IOException 135 { 136 m_position += count; 137 return m_inputStream.skip( count ); 138 } 139 }