1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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 }