Get NPOIFS in-place-write working!

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1590556 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Nick Burch 2014-04-28 06:35:39 +00:00
parent 59a1590048
commit 4e984df1c9
4 changed files with 22 additions and 18 deletions

View 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) {

View 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
@ -57,10 +56,18 @@ public class FileBackedDataSource extends DataSource {
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) {

View 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({

View 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;