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  
21  
22  package org.apache.james.util.io;
23  
24  import java.io.BufferedInputStream;
25  import java.io.File;
26  import java.io.FileInputStream;
27  import java.io.IOException;
28  import java.io.InputStream;
29  
30  public class ResettableFileInputStream
31      extends InputStream
32  {
33      protected static final int DEFAULT_BUFFER_SIZE = 1024;
34  
35      protected final String m_filename;
36      protected int m_bufferSize;
37      protected InputStream m_inputStream;
38      protected long m_position;
39      protected long m_mark;
40      protected boolean m_isMarkSet;
41  
42      public ResettableFileInputStream( final File file )
43          throws IOException
44      {
45          this( file.getCanonicalPath() );
46      }
47  
48      public ResettableFileInputStream( final String filename )
49          throws IOException
50      {
51          this( filename, DEFAULT_BUFFER_SIZE );
52      }
53  
54      public ResettableFileInputStream( final String filename, final int bufferSize )
55          throws IOException
56      {
57          m_bufferSize = bufferSize;
58          m_filename = filename;
59          m_position = 0;
60  
61          m_inputStream = newStream();
62      }
63  
64      public void mark( final int readLimit )
65      {
66          m_isMarkSet = true;
67          m_mark = m_position;
68          m_inputStream.mark( readLimit );
69      }
70  
71      public boolean markSupported()
72      {
73          return true;
74      }
75  
76      public void reset()
77          throws IOException
78      {
79          if( !m_isMarkSet )
80          {
81              throw new IOException( "Unmarked Stream" );
82          }
83          try
84          {
85              m_inputStream.reset();
86          }
87          catch( final IOException ioe )
88          {
89              try
90              {
91                  m_inputStream.close();
92                  m_inputStream = newStream();
93                  m_inputStream.skip( m_mark );
94                  m_position = m_mark;
95              }
96              catch( final Exception e )
97              {
98                  throw new IOException( "Cannot reset current Stream: " + e.getMessage() );
99              }
100         }
101     }
102 
103     protected InputStream newStream()
104         throws IOException
105     {
106         return new BufferedInputStream( new FileInputStream( m_filename ), m_bufferSize );
107     }
108 
109     public int available()
110         throws IOException
111     {
112         return m_inputStream.available();
113     }
114 
115     public void close() throws IOException
116     {
117         m_inputStream.close();
118     }
119 
120     public int read() throws IOException
121     {
122         m_position++;
123         return m_inputStream.read();
124     }
125 
126     public int read( final byte[] bytes, final int offset, final int length )
127         throws IOException
128     {
129         final int count = m_inputStream.read( bytes, offset, length );
130         m_position += count;
131         return count;
132     }
133 
134     public long skip( final long count )
135         throws IOException
136     {
137         m_position += count;
138         return m_inputStream.skip( count );
139     }
140 }