Я пытаюсь написать виртуальный класс файлов в Java. Я думаю, что фрагменты моего кода ниже достаточно просты, чтобы увидеть проблему. По сути, я должен заставить свой буфер перематывать () в странных местах, чтобы мой пример работал (помечен как вызовы принуждения к огромному (ниже)). Я неправильно понимаю использование запросов на базовый канал и позиционирование в буфере. Может кто-нибудь сказать мне, что я делаю не так. Я уверен, что это простое недоразумение. Я надеюсь, что мне придется избежать вызова empty_Hack (), потому что мой класс представляет собой структуру данных с произвольным доступом, и вы не можете сказать, в каком порядке вы будете читать и писать, а мой тест очень предсказуем и нереалистичен c в том, как он будет использоваться. .
Вот выдержки из моего класса:
public class FileStorageFloat64<U extends DoubleCoder & Allocatable<U>>
implements IndexedDataSource<U>, Allocatable<FileStorageFloat64<U>>
{
private final long numElements;
private final U type;
private final double[] tmpArray;
private final long byteCount;
private final File file;
private final RandomAccessFile raf;
private final FileChannel channel;
private final MappedByteBuffer buffer;
public FileStorageFloat64(long numElements, U type) {
this.numElements = numElements;
this.type = type.allocate();
this.tmpArray = new double[type.doubleCount()];
this.byteCount = numElements * type.doubleCount() * 8;
try {
this.file = File.createTempFile("Storage", ".storage");
this.file.deleteOnExit();
this.raf = new RandomAccessFile(file, "rw");
this.channel = raf.getChannel();
this.buffer = this.channel.map(MapMode.READ_WRITE, 0, this.byteCount);
for (long i = 0; i < this.byteCount; i++) {
this.buffer.put((byte)0);
}
this.buffer.rewind();
} catch (IOException e) {
throw new IllegalArgumentException(e.getMessage());
}
}
@Override
public void set(long index, U value) {
if (index < 0 || index >= numElements)
throw new IllegalArgumentException("storage index out of bounds");
synchronized(this) {
try {
value.toDoubleArray(this.tmpArray, 0);
long pos = index * this.type.doubleCount() * 8;
this.channel.position(pos);
for (int i = 0; i < this.tmpArray.length; i++) {
this.buffer.putDouble(this.tmpArray[i]);
}
} catch (IOException e) {
throw new IllegalArgumentException(e.getMessage());
}
}
}
@Override
public void get(long index, U value) {
if (index < 0 || index >= this.numElements)
throw new IllegalArgumentException("storage index out of bounds");
synchronized(this) {
try {
long pos = index * this.type.doubleCount() * 8;
this.channel.position(pos);
for (int i = 0; i < this.tmpArray.length; i++) {
this.tmpArray[i] = this.buffer.getDouble();
}
value.fromDoubleArray(this.tmpArray, 0);
} catch (IOException e) {
throw new IllegalArgumentException(e.getMessage());
}
}
}
public void hugeHack() {
this.buffer.rewind();
}
А вот метод испытания:
public void run() {
final int SIZE = 40;
ComplexFloat64Member v = new ComplexFloat64Member();
FileStorageFloat64<ComplexFloat64Member> store = new FileStorageFloat64<ComplexFloat64Member>(SIZE, new ComplexFloat64Member());
assertEquals(SIZE, store.size());
for (long i = 0; i < store.size(); i++) {
v.setR(i);
v.setI(i+1);
store.set(i, v);
}
store.hugeHack();
for (long i = 0; i < store.size(); i++) {
store.get(i, v);
assertEquals(i, v.r(), 0);
assertEquals(i+1, v.i(), 0);
}
store.hugeHack();
FileStorageFloat64<ComplexFloat64Member> dup = store.duplicate(); // not shown above
dup.hugeHack();
assertEquals(store.size(), dup.size());
for (long i = 0; i < dup.size(); i++) {
dup.get(i, v);
assertEquals(i, v.r(), 0);
assertEquals(i+1, v.i(), 0);
}
}