1 23 package org.archive.io; 24 25 26 import java.io.IOException ; 27 28 29 34 public class BufferedSeekInputStream extends SeekInputStream { 35 36 37 40 final private SeekInputStream input; 41 42 43 46 final private byte[] buffer; 47 48 49 54 private int maxOffset; 55 56 57 60 private int offset; 61 62 63 70 public BufferedSeekInputStream(SeekInputStream input, int capacity) 71 throws IOException { 72 this.input = input; 73 this.buffer = new byte[capacity]; 74 buffer(); 75 } 76 77 82 private void buffer() throws IOException { 83 int remaining = buffer.length; 84 while (remaining > 0) { 85 int r = input.read(buffer, buffer.length - remaining, remaining); 86 if (r <= 0) { 87 offset = 0; 89 maxOffset = buffer.length - remaining; 90 return; 91 } 92 remaining -= r; 93 } 94 maxOffset = buffer.length; 95 offset = 0; 96 } 97 98 99 104 private void ensureBuffer() throws IOException { 105 if (offset >= maxOffset) { 106 buffer(); 107 } 108 } 109 110 111 116 private int remaining() { 117 return maxOffset - offset; 118 } 119 120 121 @Override 122 public int read() throws IOException { 123 ensureBuffer(); 124 if (maxOffset == 0) { 125 return -1; 126 } 127 int ch = buffer[offset] & 0xFF; 128 offset++; 129 return ch; 130 } 131 132 133 @Override 134 public int read(byte[] buf, int ofs, int len) throws IOException { 135 ensureBuffer(); 136 if (maxOffset == 0) { 137 return 0; 138 } 139 len = Math.min(len, remaining()); 140 System.arraycopy(buffer, offset, buf, ofs, len); 141 offset += len; 142 return len; 143 } 144 145 146 @Override 147 public int read(byte[] buf) throws IOException { 148 return read(buf, 0, buf.length); 149 } 150 151 152 @Override 153 public long skip(long c) throws IOException { 154 ensureBuffer(); 155 if (maxOffset == 0) { 156 return 0; 157 } 158 int count = (c > Integer.MAX_VALUE) ? Integer.MAX_VALUE : (int)c; 159 int skip = Math.min(count, remaining()); 160 offset += skip; 161 return skip; 162 } 163 164 165 170 public long position() throws IOException { 171 return input.position() - buffer.length + offset; 172 } 173 174 175 182 public void position(long p) throws IOException { 183 long blockStart = (input.position() - maxOffset) 184 / buffer.length * buffer.length; 185 long blockEnd = blockStart + maxOffset; 186 if ((p >= blockStart) && (p < blockEnd)) { 187 long adj = p - blockStart; 189 offset = (int)adj; 190 return; 191 } 192 positionDirect(p); 193 } 194 195 196 203 private void positionDirect(long p) throws IOException { 204 long newBlockStart = p / buffer.length * buffer.length; 205 input.position(newBlockStart); 206 buffer(); 207 offset = (int)(p % buffer.length); 208 } 209 210 213 public void close() throws IOException { 214 super.close(); 215 if(this.input!=null) { 216 this.input.close(); 217 } 218 } 219 220 221 } 222 | Popular Tags |