View Javadoc

1   /*****************************************************************
2    * Licensed to the Apache Software Foundation (ASF) under one   *
3    * or more contributor license agreements.  See the NOTICE file *
4    * distributed with this work for additional information        *
5    * regarding copyright ownership.  The ASF licenses this file   *
6    * to you under the Apache License, Version 2.0 (the            *
7    * "License"); you may not use this file except in compliance   *
8    * with the License.  You may obtain a copy of the License at   *
9    *                                                              *
10   *   http://www.apache.org/licenses/LICENSE-2.0                 *
11   *                                                              *
12   * Unless required by applicable law or agreed to in writing,   *
13   * software distributed under the License is distributed on an  *
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
15   * KIND, either express or implied.  See the License for the    *
16   * specific language governing permissions and limitations      *
17   * under the License.                                           *
18   ****************************************************************/
19  
20  package org.apache.james.util.io;
21  
22  import java.io.BufferedInputStream;
23  import java.io.File;
24  import java.io.FileInputStream;
25  import java.io.IOException;
26  import java.io.InputStream;
27  
28  /***
29   * @author  Federico Barbieri <fede@apache.org>
30   */
31  public class ResettableFileInputStream
32      extends InputStream
33  {
34      protected static final int DEFAULT_BUFFER_SIZE = 1024;
35  
36      protected final String m_filename;
37      protected int m_bufferSize;
38      protected InputStream m_inputStream;
39      protected long m_position;
40      protected long m_mark;
41      protected boolean m_isMarkSet;
42  
43      public ResettableFileInputStream( final File file )
44          throws IOException
45      {
46          this( file.getCanonicalPath() );
47      }
48  
49      public ResettableFileInputStream( final String filename )
50          throws IOException
51      {
52          this( filename, DEFAULT_BUFFER_SIZE );
53      }
54  
55      public ResettableFileInputStream( final String filename, final int bufferSize )
56          throws IOException
57      {
58          m_bufferSize = bufferSize;
59          m_filename = filename;
60          m_position = 0;
61  
62          m_inputStream = newStream();
63      }
64  
65      public void mark( final int readLimit )
66      {
67          m_isMarkSet = true;
68          m_mark = m_position;
69          m_inputStream.mark( readLimit );
70      }
71  
72      public boolean markSupported()
73      {
74          return true;
75      }
76  
77      public void reset()
78          throws IOException
79      {
80          if( !m_isMarkSet )
81          {
82              throw new IOException( "Unmarked Stream" );
83          }
84          try
85          {
86              m_inputStream.reset();
87          }
88          catch( final IOException ioe )
89          {
90              try
91              {
92                  m_inputStream.close();
93                  m_inputStream = newStream();
94                  m_inputStream.skip( m_mark );
95                  m_position = m_mark;
96              }
97              catch( final Exception e )
98              {
99                  throw new IOException( "Cannot reset current Stream: " + e.getMessage() );
100             }
101         }
102     }
103 
104     protected InputStream newStream()
105         throws IOException
106     {
107         return new BufferedInputStream( new FileInputStream( m_filename ), m_bufferSize );
108     }
109 
110     public int available()
111         throws IOException
112     {
113         return m_inputStream.available();
114     }
115 
116     public void close() throws IOException
117     {
118         m_inputStream.close();
119     }
120 
121     public int read() throws IOException
122     {
123         m_position++;
124         return m_inputStream.read();
125     }
126 
127     public int read( final byte[] bytes, final int offset, final int length )
128         throws IOException
129     {
130         final int count = m_inputStream.read( bytes, offset, length );
131         m_position += count;
132         return count;
133     }
134 
135     public long skip( final long count )
136         throws IOException
137     {
138         m_position += count;
139         return m_inputStream.skip( count );
140     }
141 }