changeset 668:c609aa9a8a2c

ReadonlyFileChannelDataSource
author Devel 2
date Fri, 17 Nov 2017 14:57:06 +0100
parents 78750e3f3ca5
children 03684e7b9912
files stress-tester/src/main/java/com/passus/st/reader/nc/ReadonlyFileChannelDataSource.java stress-tester/src/test/java/com/passus/st/reader/nc/ReadonlyFileChannelDataSourceTest.java stress-tester/src/test/resources/com/passus/st/nc/sequence_file
diffstat 3 files changed, 174 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stress-tester/src/main/java/com/passus/st/reader/nc/ReadonlyFileChannelDataSource.java	Fri Nov 17 14:57:06 2017 +0100
@@ -0,0 +1,133 @@
+package com.passus.st.reader.nc;
+
+import com.passus.commons.Assert;
+import com.passus.data.DataSource;
+import java.io.File;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.channels.FileChannel;
+import java.nio.file.Path;
+import java.nio.file.StandardOpenOption;
+
+/**
+ *
+ * @author Mirosław Hawrot
+ */
+public class ReadonlyFileChannelDataSource implements DataSource {
+
+    private final FileChannel ch;
+
+    private long startPosition = -1;
+
+    private long endPosition = -1;
+
+    private ByteBuffer dataBb;
+
+    private byte[] data;
+
+    public ReadonlyFileChannelDataSource(File file) throws IOException {
+        this(file.toPath());
+    }
+
+    public ReadonlyFileChannelDataSource(File file, long startPosition, long endPosition) throws IOException {
+        this(file.toPath(), startPosition, endPosition);
+    }
+
+    public ReadonlyFileChannelDataSource(Path path) throws IOException {
+        this(FileChannel.open(path, StandardOpenOption.READ));
+    }
+
+    public ReadonlyFileChannelDataSource(Path path, long startPosition, long endPosition) throws IOException {
+        this(FileChannel.open(path, StandardOpenOption.READ), startPosition, endPosition);
+    }
+
+    public ReadonlyFileChannelDataSource(FileChannel ch) throws IOException {
+        this(ch, 0, ch.size());
+    }
+
+    public ReadonlyFileChannelDataSource(FileChannel ch, long startPosition, long endPosition) {
+        Assert.greaterOrEqualZero(startPosition, "startPosition");
+        Assert.greaterOrEqualZero(endPosition, "endPosition");
+        Assert.notNull(ch, "channel");
+        if (startPosition > endPosition) {
+            throw new IllegalArgumentException("endPosition should be grater than startPosition.");
+        }
+
+        this.ch = ch;
+        this.startPosition = startPosition;
+        this.endPosition = endPosition;
+    }
+
+    @Override
+    public boolean isWritable() {
+        return true;
+    }
+
+    @Override
+    public boolean isReadable() {
+        return false;
+    }
+
+    @Override
+    public void open() {
+
+    }
+
+    @Override
+    public void close() throws IOException {
+        dataBb = null;
+        data = null;
+    }
+
+    @Override
+    public void reset() {
+
+    }
+
+    @Override
+    public int available() {
+        try {
+            return (int) (endPosition - ch.position());
+        } catch (Exception e) {
+            throw new RuntimeException(e.getMessage(), e);
+        }
+    }
+
+    @Override
+    public void mark() {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    @Override
+    public void rewind() {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    @Override
+    public int write(byte[] data, int offset, int length) throws IOException {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    @Override
+    public int read(byte[] data, int offset, int length) throws IOException {
+        if (length == 0) {
+            return 0;
+        }
+
+        ByteBuffer dataBb = (this.data == data ? this.dataBb : ByteBuffer.wrap(data));
+        
+        int available = available();
+        int limit = Math.min(offset + length, dataBb.capacity());
+        if( limit > available ) {
+            limit = available;
+        }
+        
+        dataBb.limit(limit);
+        dataBb.position(offset);
+
+        this.dataBb = dataBb;
+        this.data = data;
+        return ch.read(dataBb, startPosition);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stress-tester/src/test/java/com/passus/st/reader/nc/ReadonlyFileChannelDataSourceTest.java	Fri Nov 17 14:57:06 2017 +0100
@@ -0,0 +1,40 @@
+package com.passus.st.reader.nc;
+
+import com.passus.commons.utils.ResourceUtils;
+import com.passus.data.ByteBuff;
+import com.passus.data.HeapByteBuff;
+import java.io.File;
+import java.util.Arrays;
+import org.apache.commons.io.FileUtils;
+import static org.testng.AssertJUnit.*;
+import org.testng.annotations.Test;
+
+/**
+ *
+ * @author Mirosław Hawrot
+ */
+public class ReadonlyFileChannelDataSourceTest {
+
+    @Test
+    public void testRead_AllFile() throws Exception {
+        File file = ResourceUtils.getFile("com/passus/st/nc/sequence_file");
+        ReadonlyFileChannelDataSource ds = new ReadonlyFileChannelDataSource(file);
+        ByteBuff buff = new HeapByteBuff();
+        ds.read(buff);
+
+        byte[] expected = FileUtils.readFileToByteArray(file);
+        assertEquals(expected, buff.toArray());
+    }
+
+    @Test(enabled = false)
+    public void testRead_Chunk() throws Exception {
+        File file = ResourceUtils.getFile("com/passus/st/nc/sequence_file");
+        ReadonlyFileChannelDataSource ds = new ReadonlyFileChannelDataSource(file, 1, 3);
+        ByteBuff buff = new HeapByteBuff();
+        ds.read(buff);
+
+        byte[] expected = FileUtils.readFileToByteArray(file);
+        expected = Arrays.copyOfRange(expected, 1, 3);
+        assertEquals(expected, buff.toArray());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stress-tester/src/test/resources/com/passus/st/nc/sequence_file	Fri Nov 17 14:57:06 2017 +0100
@@ -0,0 +1,1 @@
+123456789
\ No newline at end of file