001: /****************************************************************
002: * Licensed to the Apache Software Foundation (ASF) under one *
003: * or more contributor license agreements. See the NOTICE file *
004: * distributed with this work for additional information *
005: * regarding copyright ownership. The ASF licenses this file *
006: * to you under the Apache License, Version 2.0 (the *
007: * "License"); you may not use this file except in compliance *
008: * with the License. You may obtain a copy of the License at *
009: * *
010: * http://www.apache.org/licenses/LICENSE-2.0 *
011: * *
012: * Unless required by applicable law or agreed to in writing, *
013: * software distributed under the License is distributed on an *
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
015: * KIND, either express or implied. See the License for the *
016: * specific language governing permissions and limitations *
017: * under the License. *
018: ****************************************************************/package org.apache.james.util.io;
019:
020: import java.io.BufferedInputStream;
021: import java.io.File;
022: import java.io.FileInputStream;
023: import java.io.IOException;
024: import java.io.InputStream;
025:
026: /**
027: * @author Federico Barbieri <fede@apache.org>
028: */
029: public class ResettableFileInputStream extends InputStream {
030: protected static final int DEFAULT_BUFFER_SIZE = 1024;
031:
032: protected final String m_filename;
033: protected int m_bufferSize;
034: protected InputStream m_inputStream;
035: protected long m_position;
036: protected long m_mark;
037: protected boolean m_isMarkSet;
038:
039: public ResettableFileInputStream(final File file)
040: throws IOException {
041: this (file.getCanonicalPath());
042: }
043:
044: public ResettableFileInputStream(final String filename)
045: throws IOException {
046: this (filename, DEFAULT_BUFFER_SIZE);
047: }
048:
049: public ResettableFileInputStream(final String filename,
050: final int bufferSize) throws IOException {
051: m_bufferSize = bufferSize;
052: m_filename = filename;
053: m_position = 0;
054:
055: m_inputStream = newStream();
056: }
057:
058: public void mark(final int readLimit) {
059: m_isMarkSet = true;
060: m_mark = m_position;
061: m_inputStream.mark(readLimit);
062: }
063:
064: public boolean markSupported() {
065: return true;
066: }
067:
068: public void reset() throws IOException {
069: if (!m_isMarkSet) {
070: throw new IOException("Unmarked Stream");
071: }
072: try {
073: m_inputStream.reset();
074: } catch (final IOException ioe) {
075: try {
076: m_inputStream.close();
077: m_inputStream = newStream();
078: m_inputStream.skip(m_mark);
079: m_position = m_mark;
080: } catch (final Exception e) {
081: throw new IOException("Cannot reset current Stream: "
082: + e.getMessage());
083: }
084: }
085: }
086:
087: protected InputStream newStream() throws IOException {
088: return new BufferedInputStream(new FileInputStream(m_filename),
089: m_bufferSize);
090: }
091:
092: public int available() throws IOException {
093: return m_inputStream.available();
094: }
095:
096: public void close() throws IOException {
097: m_inputStream.close();
098: }
099:
100: public int read() throws IOException {
101: m_position++;
102: return m_inputStream.read();
103: }
104:
105: public int read(final byte[] bytes, final int offset,
106: final int length) throws IOException {
107: final int count = m_inputStream.read(bytes, offset, length);
108: m_position += count;
109: return count;
110: }
111:
112: public long skip(final long count) throws IOException {
113: m_position += count;
114: return m_inputStream.skip(count);
115: }
116: }
|