• R/O
  • HTTP
  • SSH
  • HTTPS

dictzip-java: Commit


Commit MetaInfo

Revision846f4eb85573a90e025ff125142b111d3fc08361 (tree)
Zeit2022-04-16 20:52:36
AutorHiroshi Miura <miurahr@linu...>
CommiterGitHub

Log Message

RandomAccessInputStream: Support java.nio.channels.FileChannel (#49)

* RAIS: Support java.nio.channels.FileChannel

Signed-off-by: Hiroshi Miura <miurahr@linux.com>

Ändern Zusammenfassung

Diff

--- a/dictzip-lib/src/main/java/org/dict/zip/RandomAccessInputStream.java
+++ b/dictzip-lib/src/main/java/org/dict/zip/RandomAccessInputStream.java
@@ -25,6 +25,8 @@ import org.jetbrains.annotations.NotNull;
2525 import java.io.IOException;
2626 import java.io.InputStream;
2727 import java.io.RandomAccessFile;
28+import java.nio.ByteBuffer;
29+import java.nio.channels.FileChannel;
2830
2931 /**
3032 * RandomAccessInputStream.
@@ -36,24 +38,26 @@ import java.io.RandomAccessFile;
3638 public class RandomAccessInputStream extends InputStream {
3739 private static final int DEFAULT_BUFSIZE = 4096;
3840 private final RandomAccessFile in;
39- private final byte[] inbuf;
41+ private final ByteBuffer byteBuffer;
4042 private final int bufsize;
4143
4244 private long currentpos = 0;
4345 private long startpos = -1;
4446 private long endpos = -1;
4547 private long mark = 0;
48+ private FileChannel fileChannel;
4649
4750
4851 /**
4952 * Constructor of RandomAccessInputStream, accept RandomAccessFile and buffer size.
50- * @param inFile RandomAccessFile file.
51- * @param bufsize buffer size.
53+ * @param inFile RandomAccessFile
54+ * @param bufsize buffer size
5255 */
5356 public RandomAccessInputStream(final RandomAccessFile inFile, final int bufsize) {
54- this.in = inFile;
57+ in = inFile;
5558 this.bufsize = bufsize;
56- inbuf = new byte[bufsize];
59+ fileChannel = inFile.getChannel();
60+ byteBuffer = ByteBuffer.allocate(bufsize);
5761 }
5862
5963 /**
@@ -77,6 +81,14 @@ public class RandomAccessInputStream extends InputStream {
7781 }
7882
7983 /**
84+ * Get an unique FileChannel Object related to the file.
85+ * @return FileChannel object.
86+ */
87+ public final FileChannel getChannel() {
88+ return fileChannel;
89+ }
90+
91+ /**
8092 * {@inheritDoc}
8193 */
8294 @Override
@@ -94,6 +106,7 @@ public class RandomAccessInputStream extends InputStream {
94106 @Override
95107 public final void close() throws IOException {
96108 in.close();
109+ fileChannel = null;
97110 }
98111
99112 /**
@@ -103,7 +116,7 @@ public class RandomAccessInputStream extends InputStream {
103116 * @exception IOException if an I/O error has occurred.
104117 */
105118 public final long length() throws IOException {
106- return in.length();
119+ return fileChannel.size();
107120 }
108121
109122 public final int getLength() throws IOException {
@@ -162,23 +175,25 @@ public class RandomAccessInputStream extends InputStream {
162175 * @param pos position to read.
163176 * @return -1 when position is greater than the file's current size, otherwise byte value.
164177 */
165- public int read(long pos) {
178+ public synchronized int read(long pos) {
166179 if (pos < startpos || pos > endpos) {
167180 long blockstart = (pos/ bufsize) * bufsize;
168- int n;
181+ int n = 0;
169182 try {
170- in.seek(blockstart);
171- n = in.read(inbuf);
183+ fileChannel.position(blockstart);
184+ byteBuffer.clear();
185+ n += fileChannel.read(byteBuffer);
172186 } catch (IOException e) {
173187 return -1;
174188 }
189+ byteBuffer.flip();
175190 startpos = blockstart;
176191 endpos = blockstart + n - 1;
177192 if (pos < startpos || pos > endpos) {
178193 return -1;
179194 }
180195 }
181- return inbuf[(int) (pos - startpos)] & 0xff;
196+ return byteBuffer.get((int) (pos - startpos)) & 0xff;
182197 }
183198
184199 /**
@@ -186,17 +201,27 @@ public class RandomAccessInputStream extends InputStream {
186201 */
187202 @Override
188203 public final int read(final byte @NotNull [] buf, final int off, final int len) throws IOException {
189- int idx = 0;
190- while (idx < len) {
191- int c = read(currentpos);
192- if (c == -1) {
193- return idx;
194- } else {
195- buf[off + idx++] = (byte) c;
196- currentpos++;
204+ if (currentpos < startpos || currentpos > endpos) {
205+ long blockstart = (currentpos / bufsize) * bufsize;
206+ long n = 0;
207+ try {
208+ fileChannel.position(blockstart);
209+ byteBuffer.clear();
210+ n += fileChannel.read(byteBuffer);
211+ } catch (IOException e) {
212+ return -1;
213+ }
214+ startpos = blockstart;
215+ endpos = blockstart + n - 1;
216+ if (currentpos < startpos || currentpos > endpos) {
217+ return -1;
197218 }
198219 }
199- return idx;
220+ byteBuffer.position((int) (currentpos - startpos));
221+ int size = Math.min(Math.min(len, (int)(length() - currentpos)), byteBuffer.remaining());
222+ byteBuffer.get(buf, off, size);
223+ currentpos += size;
224+ return size;
200225 }
201226
202227 /**
@@ -206,14 +231,9 @@ public class RandomAccessInputStream extends InputStream {
206231 * @exception IOException if an I/O error has occurred.
207232 */
208233 public final void readFully(final byte[] buf) throws IOException {
209- int idx = 0;
210- while (idx < buf.length) {
211- int c = read(currentpos);
212- if (c == -1) {
213- throw new IOException();
214- }
215- buf[idx++] = (byte) c;
216- currentpos++;
234+ int offset = read(buf, 0, buf.length);
235+ while (offset < buf.length) {
236+ offset += read(buf, offset, buf.length - offset);
217237 }
218238 }
219239
@@ -221,7 +241,7 @@ public class RandomAccessInputStream extends InputStream {
221241 * {@inheritDoc}
222242 */
223243 @Override
224- public final synchronized void reset() throws IOException {
244+ public final synchronized void reset() {
225245 currentpos = mark;
226246 }
227247
@@ -231,7 +251,6 @@ public class RandomAccessInputStream extends InputStream {
231251 * when specified position is beyond of end of the file, position is set to end of file.
232252 *
233253 * @param pos file position in byte.
234- * @exception IOException if an I/O error has occurred.
235254 */
236255 public final void seek(final long pos) throws IOException {
237256 if (pos < 0) {
--- a/dictzip-lib/src/test/java/org/dict/zip/DictZipInputStreamTest.java
+++ b/dictzip-lib/src/test/java/org/dict/zip/DictZipInputStreamTest.java
@@ -268,8 +268,8 @@ public class DictZipInputStreamTest {
268268 }
269269 // read trailer
270270 din.readTrailer();
271- assertEquals(din.getCrc(), 0x024d1f37);
272- assertEquals(din.getLength(), 383783);
271+ assertEquals(0x024d1f37, din.getCrc());
272+ assertEquals(383783, din.getLength());
273273 }
274274 }
275275
--- a/dictzip-lib/src/test/java/org/dict/zip/RandomAccessInputStreamTest.java
+++ b/dictzip-lib/src/test/java/org/dict/zip/RandomAccessInputStreamTest.java
@@ -219,14 +219,16 @@ public class RandomAccessInputStreamTest {
219219
220220 @Test
221221 public void testLastBytes() throws Exception {
222- RandomAccessInputStream instance = new RandomAccessInputStream(dataFile, "r");
223- instance.seek(136848);
224- byte[] buf = new byte[9];
225- int len = instance.read(buf, 0, buf.length);
226- assertEquals(8, len);
227- assertEquals(5, buf[len - 2]);
228- assertEquals(0, buf[len - 1]);
229- long pos = instance.position();
222+ long pos;
223+ try (RandomAccessInputStream instance = new RandomAccessInputStream(dataFile, "r")) {
224+ instance.seek(136848);
225+ byte[] buf = new byte[9];
226+ int len = instance.read(buf, 0, buf.length);
227+ assertEquals(8, len);
228+ assertEquals(5, buf[len - 2]);
229+ assertEquals(0, buf[len - 1]);
230+ pos = instance.position();
231+ }
230232 assertEquals(136856, pos);
231233 }
232234 }
Show on old repository browser