]> source.dussan.org Git - poi.git/commitdiff
Get NPOIFS in-place-write working!
authorNick Burch <nick@apache.org>
Mon, 28 Apr 2014 06:35:39 +0000 (06:35 +0000)
committerNick Burch <nick@apache.org>
Mon, 28 Apr 2014 06:35:39 +0000 (06:35 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1590556 13f79535-47bb-0310-9956-ffa450edef68

src/java/org/apache/poi/poifs/filesystem/NPOIFSFileSystem.java
src/java/org/apache/poi/poifs/nio/FileBackedDataSource.java
src/testcases/org/apache/poi/hpsf/basic/AllPOIHPSFBasicTests.java
src/testcases/org/apache/poi/hpsf/basic/TestWrite.java

index dbc1783684a127cc4ba580e15249a0fb98968185..3f60b4bda2453a8561429098c0891d88962d0536 100644 (file)
@@ -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.</p> 
      *  
-     * @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) {
index 19649862665ac6e250af13df348cbaa03661014a..fc0009c953fb5bfb6b7263ac82aff340f32de488 100644 (file)
@@ -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) {
index b573c28d905cba420ed9c76197a9dd68c5d3d0f4..dbb56451ac2dcbaa44bb757aa22ea9664b7b2a31 100644 (file)
@@ -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({
index e5ddc62fd4f57aba65871f66fc6baa0722d90cfa..c6552a7a2ea535c354adba6f1224b4c7e5e1950f 100644 (file)
@@ -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;