Merge pull request #84 from dscho/random-access-file

Write support for the RandomAccessFile
This commit is contained in:
Joshua Warner
2013-10-21 09:38:44 -07:00
5 changed files with 193 additions and 24 deletions

View File

@ -11,29 +11,40 @@
package java.io;
import java.lang.IllegalArgumentException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
public class RandomAccessFile {
private long peer;
private File file;
private long position = 0;
private long length;
private boolean allowWrite;
public RandomAccessFile(String name, String mode)
throws FileNotFoundException
{
if (! mode.equals("r")) throw new IllegalArgumentException();
file = new File(name);
this(new File(name), mode);
}
public RandomAccessFile(File file, String mode)
throws FileNotFoundException
{
if (file == null) throw new NullPointerException();
if (mode.equals("rw")) allowWrite = true;
else if (! mode.equals("r")) throw new IllegalArgumentException();
this.file = file;
open();
}
private void open() throws FileNotFoundException {
long[] result = new long[2];
open(file.getPath(), result);
open(file.getPath(), allowWrite, result);
peer = result[0];
length = result[1];
}
private static native void open(String name, long[] result)
private static native void open(String name, boolean allowWrite, long[] result)
throws FileNotFoundException;
private void refresh() throws IOException {
@ -53,7 +64,7 @@ public class RandomAccessFile {
}
public void seek(long position) throws IOException {
if (position < 0 || position > length()) throw new IOException();
if (position < 0 || (!allowWrite && position > length())) throw new IOException();
this.position = position;
}
@ -122,6 +133,14 @@ public class RandomAccessFile {
private static native int readBytes(long peer, long position, byte[] buffer,
int offset, int length);
public void write(int b) throws IOException {
int count = writeBytes(peer, position, new byte[] { (byte)b }, 0, 1);
if (count > 0) position += count;
}
private static native int writeBytes(long peer, long position, byte[] buffer,
int offset, int length);
public void close() throws IOException {
if (peer != 0) {
close(peer);
@ -130,4 +149,50 @@ public class RandomAccessFile {
}
private static native void close(long peer);
public FileChannel getChannel() {
return new FileChannel() {
public void close() {
if (peer != 0) RandomAccessFile.close(peer);
}
public boolean isOpen() {
return peer != 0;
}
public int read(ByteBuffer dst, long position) throws IOException {
if (!dst.hasArray()) throw new IOException("Cannot handle " + dst.getClass());
// TODO: this needs to be synchronized on the Buffer, no?
byte[] array = dst.array();
return readBytes(peer, position, array, dst.position(), dst.remaining());
}
public int read(ByteBuffer dst) throws IOException {
int count = read(dst, position);
if (count > 0) position += count;
return count;
}
public int write(ByteBuffer src, long position) throws IOException {
if (!src.hasArray()) throw new IOException("Cannot handle " + src.getClass());
byte[] array = src.array();
return writeBytes(peer, position, array, src.position(), src.remaining());
}
public int write(ByteBuffer src) throws IOException {
int count = write(src, position);
if (count > 0) position += count;
return count;
}
public long position() throws IOException {
return getFilePointer();
}
public FileChannel position(long position) throws IOException {
seek(position);
return this;
}
};
}
}

View File

@ -0,0 +1,14 @@
/* Copyright (c) 2008-2013, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
that the above copyright notice and this permission notice appear
in all copies.
There is NO WARRANTY for this software. See license.txt for
details. */
package java.nio;
public class BufferUnderflowException extends RuntimeException {
}

View File

@ -244,4 +244,13 @@ public abstract class ByteBuffer
protected void checkGet(int position, int amount) {
if (amount > limit-position) throw new IndexOutOfBoundsException();
}
public ByteBuffer order(ByteOrder order) {
if (order != ByteOrder.BIG_ENDIAN) throw new UnsupportedOperationException();
return this;
}
public ByteOrder order() {
return ByteOrder.BIG_ENDIAN;
}
}

View File

@ -0,0 +1,33 @@
/* Copyright (c) 2008-2013, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
that the above copyright notice and this permission notice appear
in all copies.
There is NO WARRANTY for this software. See license.txt for
details. */
package java.nio.channels;
import java.io.IOException;
import java.nio.ByteBuffer;
public abstract class FileChannel implements Channel {
public static enum MapMode {
PRIVATE, READ_ONLY, READ_WRITE
};
public abstract int read(ByteBuffer dst) throws IOException;
public abstract int read(ByteBuffer dst, long position) throws IOException;
public abstract int write(ByteBuffer dst) throws IOException;
public abstract int write(ByteBuffer dst, long position) throws IOException;
public abstract long position() throws IOException;
public abstract FileChannel position(long position) throws IOException;
}