From 4e984df1c9acc6754292660d835f809ad2fbeb77 Mon Sep 17 00:00:00 2001 From: Nick Burch Date: Mon, 28 Apr 2014 06:35:39 +0000 Subject: [PATCH] Get NPOIFS in-place-write working! git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1590556 13f79535-47bb-0310-9956-ffa450edef68 --- .../poifs/filesystem/NPOIFSFileSystem.java | 9 ++++--- .../poi/poifs/nio/FileBackedDataSource.java | 27 ++++++++++++------- .../poi/hpsf/basic/AllPOIHPSFBasicTests.java | 2 -- .../org/apache/poi/hpsf/basic/TestWrite.java | 2 -- 4 files changed, 22 insertions(+), 18 deletions(-) diff --git a/src/java/org/apache/poi/poifs/filesystem/NPOIFSFileSystem.java b/src/java/org/apache/poi/poifs/filesystem/NPOIFSFileSystem.java index dbc1783684..3f60b4bda2 100644 --- a/src/java/org/apache/poi/poifs/filesystem/NPOIFSFileSystem.java +++ b/src/java/org/apache/poi/poifs/filesystem/NPOIFSFileSystem.java @@ -164,6 +164,7 @@ public class NPOIFSFileSystem extends BlockStore { this( (new RandomAccessFile(file, readOnly? "r" : "rw")).getChannel(), + readOnly, true ); } @@ -176,17 +177,17 @@ public class NPOIFSFileSystem extends BlockStore * when you're done to have the underlying Channel closed, as the channel is * kept open during normal operation to read the data out.

* - * @param channel the FileChannel from which to read the data + * @param channel the FileChannel from which to read and write the data * * @exception IOException on errors reading, or on invalid data */ public NPOIFSFileSystem(FileChannel channel) throws IOException { - this(channel, false); + this(channel, false, false); } - private NPOIFSFileSystem(FileChannel channel, boolean closeChannelOnError) + private NPOIFSFileSystem(FileChannel channel, boolean readOnly, boolean closeChannelOnError) throws IOException { this(false); @@ -200,7 +201,7 @@ public class NPOIFSFileSystem extends BlockStore _header = new HeaderBlock(headerBuffer); // Now process the various entries - _data = new FileBackedDataSource(channel); + _data = new FileBackedDataSource(channel, readOnly); readCoreContents(); } catch(IOException e) { if(closeChannelOnError) { diff --git a/src/java/org/apache/poi/poifs/nio/FileBackedDataSource.java b/src/java/org/apache/poi/poifs/nio/FileBackedDataSource.java index 1964986266..fc0009c953 100644 --- a/src/java/org/apache/poi/poifs/nio/FileBackedDataSource.java +++ b/src/java/org/apache/poi/poifs/nio/FileBackedDataSource.java @@ -31,13 +31,10 @@ import org.apache.poi.util.IOUtils; /** * A POIFS {@link DataSource} backed by a File - * - * TODO - Return the ByteBuffers in such a way that in RW mode, - * changes to the buffer end up on the disk (will fix the HPSF TestWrite - * currently failing unit test when done) */ public class FileBackedDataSource extends DataSource { private FileChannel channel; + private boolean writable; @SuppressWarnings("resource") public FileBackedDataSource(File file) throws FileNotFoundException { @@ -45,10 +42,12 @@ public class FileBackedDataSource extends DataSource { throw new FileNotFoundException(file.toString()); } this.channel = (new RandomAccessFile(file, "r")).getChannel(); + this.writable = false; } - public FileBackedDataSource(FileChannel channel) { + public FileBackedDataSource(FileChannel channel, boolean readOnly) { this.channel = channel; + this.writable = !readOnly; } @Override @@ -56,11 +55,19 @@ public class FileBackedDataSource extends DataSource { if(position >= size()) { throw new IllegalArgumentException("Position " + position + " past the end of the file"); } - - // Read - channel.position(position); - ByteBuffer dst = ByteBuffer.allocate(length); - int worked = IOUtils.readFully(channel, dst); + + // Do we read or map (for read/write? + ByteBuffer dst; + int worked = -1; + if (writable) { + dst = channel.map(FileChannel.MapMode.READ_WRITE, position, length); + worked = 0; + } else { + // Read + channel.position(position); + dst = ByteBuffer.allocate(length); + worked = IOUtils.readFully(channel, dst); + } // Check if(worked == -1) { diff --git a/src/testcases/org/apache/poi/hpsf/basic/AllPOIHPSFBasicTests.java b/src/testcases/org/apache/poi/hpsf/basic/AllPOIHPSFBasicTests.java index b573c28d90..dbb56451ac 100644 --- a/src/testcases/org/apache/poi/hpsf/basic/AllPOIHPSFBasicTests.java +++ b/src/testcases/org/apache/poi/hpsf/basic/AllPOIHPSFBasicTests.java @@ -21,8 +21,6 @@ import org.junit.runner.RunWith; import org.junit.runners.Suite; /** * Test suite for org.apache.poi.hpsf.basic - * - * @author Josh Micich */ @RunWith(Suite.class) @Suite.SuiteClasses({ diff --git a/src/testcases/org/apache/poi/hpsf/basic/TestWrite.java b/src/testcases/org/apache/poi/hpsf/basic/TestWrite.java index e5ddc62fd4..c6552a7a2e 100644 --- a/src/testcases/org/apache/poi/hpsf/basic/TestWrite.java +++ b/src/testcases/org/apache/poi/hpsf/basic/TestWrite.java @@ -75,7 +75,6 @@ import org.apache.poi.util.IOUtils; import org.apache.poi.util.LittleEndian; import org.apache.poi.util.TempFile; import org.junit.Before; -import org.junit.Ignore; import org.junit.Test; /** @@ -811,7 +810,6 @@ public class TestWrite * without needing to stream in + out the whole kitchen sink */ @Test - @Ignore public void inPlaceNPOIFSWrite() throws Exception { NPOIFSFileSystem fs = null; DirectoryEntry root = null;