KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > core > internal > registry > BufferedRandomInputStream


1 /*******************************************************************************
2  * Copyright (c) 2005, 2006 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.core.internal.registry;
12
13 import java.io.*;
14
15 /**
16  * Provides buffered read from a java.io.RandomAccessFile.
17  */

18 public class BufferedRandomInputStream extends InputStream {
19
20     private RandomAccessFile inputFile;
21     private String JavaDoc filePath; // Canonical path to the underlying file used for logging
22
private int buffer_size; // Current size of the buffer
23
private int buffer_pos; // Current read position in the buffer
24
/**
25      * The absolute position in the file where the buffered region starts.
26      */

27     private long buffer_start = 0;
28
29     /**
30      * The current value of the RAF's file pointer.
31      */

32     private long file_pointer;
33
34     private byte buffer[];
35
36     public BufferedRandomInputStream(File file) throws IOException {
37         this(file, 2048); // default buffer size
38
}
39
40     public BufferedRandomInputStream(File file, int bufferSize) throws IOException {
41         filePath = file.getCanonicalPath();
42         inputFile = new RandomAccessFile(file, "r"); //$NON-NLS-1$
43
buffer = new byte[bufferSize];
44         file_pointer = 0;
45         resetBuffer();
46     }
47
48     private void resetBuffer() {
49         buffer_pos = 0;
50         buffer_size = 0;
51         buffer_start = 0;
52     }
53
54     private int fillBuffer() throws IOException {
55         buffer_pos = 0;
56         buffer_start = file_pointer;
57         buffer_size = inputFile.read(buffer, 0, buffer.length);
58         file_pointer += buffer_size;
59         return buffer_size;
60     }
61
62     public int read() throws IOException {
63         if (buffer_pos >= buffer_size) {
64             if (fillBuffer() <= 0)
65                 return -1;
66         }
67         return buffer[buffer_pos++] & 0xFF;
68     }
69
70     public int read(byte b[], int off, int len) throws IOException {
71         int available = buffer_size - buffer_pos;
72         if (available < 0)
73             return -1;
74         //the buffer contains all the bytes we need, so copy over and return
75
if (len <= available) {
76             System.arraycopy(buffer, buffer_pos, b, off, len);
77             buffer_pos += len;
78             return len;
79         }
80         // Use portion remaining in the buffer
81
System.arraycopy(buffer, buffer_pos, b, off, available);
82         if (fillBuffer() <= 0)
83             return available;
84         //recursive call to read again until we have the bytes we need
85
return available + read(b, off + available, len - available);
86     }
87
88     public long skip(long n) throws IOException {
89         if (n <= 0)
90             return 0;
91
92         int available = buffer_size - buffer_pos;
93         if (n <= available) {
94             buffer_pos += n;
95             return n;
96         }
97         resetBuffer();
98         final int skipped = inputFile.skipBytes((int) (n - available));
99         file_pointer += skipped;
100         return available + skipped;
101     }
102
103     public int available() throws IOException {
104         return (buffer_size - buffer_pos);
105     }
106
107     public void close() throws IOException {
108         inputFile.close();
109         inputFile = null;
110         buffer = null;
111     }
112
113     public String JavaDoc toString() {
114         return filePath;
115     }
116
117     /**
118      * Supplies functionality of the {@link java.io.RandomAccessFile#seek(long)} in
119      * a buffer-friendly manner.
120      *
121      * @param pos offset
122      * @throws IOException
123      */

124     public void seek(long pos) throws IOException {
125         if (pos >= buffer_start && pos < buffer_start + buffer_size) {
126             //seeking within the current buffer
127
buffer_pos = (int) (pos - buffer_start);
128         } else {
129             //seeking outside the buffer - just discard the buffer
130
inputFile.seek(pos);
131             file_pointer = pos;
132             resetBuffer();
133         }
134     }
135
136     /**
137      * Supplies functionality of the {@link java.io.RandomAccessFile#length()}.
138      * @return file length
139      * @throws IOException
140      */

141     public long length() throws IOException {
142         return inputFile.length();
143     }
144
145 }
146
Popular Tags