View Javadoc

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 }