Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/maven/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
我如何滥用Java';s MappedByteBuffer_Java_Nio - Fatal编程技术网

我如何滥用Java';s MappedByteBuffer

我如何滥用Java';s MappedByteBuffer,java,nio,Java,Nio,我正在尝试用Java编写一个虚拟文件类。我认为下面的代码片段足够简单,可以看出问题所在。基本上,我必须在奇怪的地方强制我的缓冲区倒带(),这样我的示例才能工作(下面标记为对hugeHack()的调用)。我误解了在底层通道上使用seek和在缓冲区内定位。有人能告诉我我做错了什么吗。我很确定这是一些简单的误解。我希望避免使用hugeHack(),因为我的类是一个随机访问的数据结构,你不知道读写的顺序,我的测试在如何使用它方面是非常可预测和不现实的 以下是我的课堂摘录: public class Fi

我正在尝试用Java编写一个虚拟文件类。我认为下面的代码片段足够简单,可以看出问题所在。基本上,我必须在奇怪的地方强制我的缓冲区倒带(),这样我的示例才能工作(下面标记为对hugeHack()的调用)。我误解了在底层通道上使用seek和在缓冲区内定位。有人能告诉我我做错了什么吗。我很确定这是一些简单的误解。我希望避免使用hugeHack(),因为我的类是一个随机访问的数据结构,你不知道读写的顺序,我的测试在如何使用它方面是非常可预测和不现实的

以下是我的课堂摘录:

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();
    }
公共类文件存储浮动64
实现IndexedDataSource,可分配
{
私人最终长婚礼;
私人最终U型;
私人决赛双[]tmpArray;
私有最终长字节数;
私人最终文件;
私人最终文件raf;
专用最终文件通道;
私有最终MappedByteBuffer缓冲区;
公共文件存储浮动64(长数值,U型){
this.numElements=numElements;
this.type=type.allocate();
this.tmpArray=new double[type.doubleCount()];
this.byteCount=numElements*type.doubleCount()*8;
试一试{
this.file=file.createTempFile(“存储”,“存储”);
this.file.deleteOnExit();
this.raf=新的随机访问文件(文件“rw”);
this.channel=raf.getChannel();
this.buffer=this.channel.map(MapMode.READ\u WRITE,0,this.byteCount);
for(长i=0;i=数值)
抛出新的IllegalArgumentException(“存储索引超出范围”);
已同步(此){
试一试{
值.toDoubleArray(this.tmpArray,0);
long pos=index*this.type.doubleCount()*8;
本通道位置(pos);
for(int i=0;i=此数值)
抛出新的IllegalArgumentException(“存储索引超出范围”);
已同步(此){
试一试{
long pos=index*this.type.doubleCount()*8;
本通道位置(pos);
for(int i=0;i
下面是一个测试方法:

    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);
        }

    }
public void run(){
最终整数大小=40;
complexfloat64成员v=新的complexfloat64成员();
FileStorageFloat64 store=newfilestoragefloat64(大小,newcomplexfloat64member());
assertEquals(SIZE,store.SIZE());
用于(长i=0;i
好的,所以我昨天花了整整一天时间,找到了一个使用ByteBuffer的解决方案;只是没有映射ByteBuffer。它比我以前的RandomAccessFile方法快10到100倍。我现在可以说这已经足够好了

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 int bufSize;
    private final File file;
    private final RandomAccessFile raf;
    private final FileChannel channel;
    private final ByteBuffer buffer;

    /**
     * 
     * @param numElements
     * @param type
     */
    public FileStorageFloat64(long numElements, U type) {
        this.numElements = numElements;
        this.type = type.allocate();
        this.tmpArray = new double[type.doubleCount()];
        this.bufSize = type.doubleCount() * 8;
        try {
            this.file = File.createTempFile("Storage", ".storage");
            this.file.deleteOnExit();
            this.raf = new RandomAccessFile(file, "rw");
            this.channel = raf.getChannel();
            // make a one element buffer
            this.buffer = ByteBuffer.allocate(bufSize);
            // fill the buffer with zeroes
            for (int i = 0; i < type.doubleCount(); i++) {
                buffer.putDouble(0);
            }
            // write zeroes to the file over and over
            channel.position(0);
            for (long i = 0; i < numElements; i++) {
                channel.write(buffer);
            }
        } catch (IOException e) {
            throw new IllegalArgumentException(e.getMessage());
        }
    }

    @Override
    public void set(long index, U value) {
        if (index < 0 || index >= this.numElements)
            throw new IllegalArgumentException("storage index out of bounds");
        synchronized(this) {
            try {
                value.toDoubleArray(this.tmpArray, 0);
                for (int i = 0; i < this.tmpArray.length; i++) {
                    this.buffer.putDouble(i*8, this.tmpArray[i]);
                }
                this.buffer.rewind();
                long pos = index * this.bufSize;
                this.channel.position(pos);
                this.channel.write(this.buffer);
            } 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 {
                buffer.rewind();
                long pos = index * bufSize;
                this.channel.position(pos);
                this.channel.read(this.buffer);
                for (int i = 0; i < this.tmpArray.length; i++) {
                    this.tmpArray[i] = this.buffer.getDouble(i*8);
                }
                value.fromDoubleArray(this.tmpArray, 0);
            } catch (IOException e) {
                throw new IllegalArgumentException(e.getMessage());
            }
        }
    }

公共类文件存储浮动64
实现IndexedDataSource,可分配
{
私人最终长婚礼;
私人最终U型;
私人决赛双[]tmpArray;
私人最终int bufSize;
私人最终文件;
私人最终文件raf;
专用最终文件通道;
专用最终字节缓冲区;
/**
* 
*@param numElements
*@param类型
*/
公共文件存储浮动64(长数值,U型){
this.numElements=numElements;
this.type=type.allocate();
this.tmpArray=new double[type.doubleCount()];
this.bufSize=type.doubleCount()*8;
试一试{
this.file=file.createTempFile(“存储”,“存储”);
this.file.deleteOnExit();
this.raf=新的随机访问文件(文件“rw”);
this.channel=raf.getChannel();
//制作一个单元素缓冲区
this.buffer=ByteBuffer.allocate(bufSize);
//用零填充缓冲区
对于(int i=0;i