提交 8b48ecdb authored 作者: noelgrandin@gmail.com's avatar noelgrandin@gmail.com

FileSystem: improve exception throwing compatibility with JDK

上级 af80d630
...@@ -23,6 +23,7 @@ Change Log ...@@ -23,6 +23,7 @@ Change Log
</li><li>Follow JDBC specification on Procedures MetaData, use P0 as </li><li>Follow JDBC specification on Procedures MetaData, use P0 as
return type of procedure. return type of procedure.
</li><li>Issue 531: IDENTITY ignored for added column. </li><li>Issue 531: IDENTITY ignored for added column.
</li><li>FileSystem: improve exception throwing compatibility with JDK
</li></ul> </li></ul>
<h2>Version 1.4.178 Beta (2014-05-02)</h2> <h2>Version 1.4.178 Beta (2014-05-02)</h2>
......
...@@ -18,6 +18,7 @@ import java.net.URL; ...@@ -18,6 +18,7 @@ import java.net.URL;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.channels.FileChannel; import java.nio.channels.FileChannel;
import java.nio.channels.FileLock; import java.nio.channels.FileLock;
import java.nio.channels.NonWritableChannelException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
...@@ -395,10 +396,12 @@ class FileDisk extends FileBase { ...@@ -395,10 +396,12 @@ class FileDisk extends FileBase {
private final RandomAccessFile file; private final RandomAccessFile file;
private final String name; private final String name;
private final boolean readOnly;
FileDisk(String fileName, String mode) throws FileNotFoundException { FileDisk(String fileName, String mode) throws FileNotFoundException {
this.file = new RandomAccessFile(fileName, mode); this.file = new RandomAccessFile(fileName, mode);
this.name = fileName; this.name = fileName;
this.readOnly = mode.equals("r");
} }
@Override @Override
...@@ -419,6 +422,10 @@ class FileDisk extends FileBase { ...@@ -419,6 +422,10 @@ class FileDisk extends FileBase {
@Override @Override
public FileChannel truncate(long newLength) throws IOException { public FileChannel truncate(long newLength) throws IOException {
// compatibility with JDK FileChannel#truncate
if (readOnly) {
throw new NonWritableChannelException();
}
if (newLength < file.length()) { if (newLength < file.length()) {
file.setLength(newLength); file.setLength(newLength);
} }
......
...@@ -12,6 +12,7 @@ import java.io.OutputStream; ...@@ -12,6 +12,7 @@ import java.io.OutputStream;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.channels.FileChannel; import java.nio.channels.FileChannel;
import java.nio.channels.FileLock; import java.nio.channels.FileLock;
import java.nio.channels.NonWritableChannelException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
...@@ -264,6 +265,10 @@ class FileMem extends FileBase { ...@@ -264,6 +265,10 @@ class FileMem extends FileBase {
@Override @Override
public FileChannel truncate(long newLength) throws IOException { public FileChannel truncate(long newLength) throws IOException {
// compatibility with JDK FileChannel#truncate
if (readOnly) {
throw new NonWritableChannelException();
}
if (newLength < size()) { if (newLength < size()) {
data.touch(readOnly); data.touch(readOnly);
pos = Math.min(pos, newLength); pos = Math.min(pos, newLength);
......
...@@ -82,28 +82,24 @@ class FileNio extends FileBase { ...@@ -82,28 +82,24 @@ class FileNio extends FileBase {
@Override @Override
public FileChannel truncate(long newLength) throws IOException { public FileChannel truncate(long newLength) throws IOException {
try { long size = channel.size();
long size = channel.size(); if (newLength < size) {
if (newLength < size) { long pos = channel.position();
long pos = channel.position(); channel.truncate(newLength);
channel.truncate(newLength); long newPos = channel.position();
long newPos = channel.position(); if (pos < newLength) {
if (pos < newLength) { // position should stay
// position should stay // in theory, this should not be needed
// in theory, this should not be needed if (newPos != pos) {
if (newPos != pos) { channel.position(pos);
channel.position(pos);
}
} else if (newPos > newLength) {
// looks like a bug in this FileChannel implementation, as
// the documentation says the position needs to be changed
channel.position(newLength);
} }
} else if (newPos > newLength) {
// looks like a bug in this FileChannel implementation, as
// the documentation says the position needs to be changed
channel.position(newLength);
} }
return this;
} catch (NonWritableChannelException e) {
throw new IOException("read only");
} }
return this;
} }
@Override @Override
......
...@@ -16,6 +16,7 @@ import java.nio.ByteBuffer; ...@@ -16,6 +16,7 @@ import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer; import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel; import java.nio.channels.FileChannel;
import java.nio.channels.FileLock; import java.nio.channels.FileLock;
import java.nio.channels.NonWritableChannelException;
import org.h2.engine.SysProperties; import org.h2.engine.SysProperties;
...@@ -203,6 +204,10 @@ class FileNioMapped extends FileBase { ...@@ -203,6 +204,10 @@ class FileNioMapped extends FileBase {
@Override @Override
public synchronized FileChannel truncate(long newLength) throws IOException { public synchronized FileChannel truncate(long newLength) throws IOException {
// compatibility with JDK FileChannel#truncate
if (mode == MapMode.READ_ONLY) {
throw new NonWritableChannelException();
}
if (newLength < size()) { if (newLength < size()) {
setFileLength(newLength); setFileLength(newLength);
} }
......
...@@ -12,6 +12,7 @@ import java.io.OutputStream; ...@@ -12,6 +12,7 @@ import java.io.OutputStream;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.channels.FileChannel; import java.nio.channels.FileChannel;
import java.nio.channels.FileLock; import java.nio.channels.FileLock;
import java.nio.channels.NonWritableChannelException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
...@@ -256,6 +257,10 @@ class FileNioMem extends FileBase { ...@@ -256,6 +257,10 @@ class FileNioMem extends FileBase {
@Override @Override
public FileChannel truncate(long newLength) throws IOException { public FileChannel truncate(long newLength) throws IOException {
// compatibility with JDK FileChannel#truncate
if (readOnly) {
throw new NonWritableChannelException();
}
if (newLength < size()) { if (newLength < size()) {
data.touch(readOnly); data.touch(readOnly);
pos = Math.min(pos, newLength); pos = Math.min(pos, newLength);
......
...@@ -15,6 +15,7 @@ import java.nio.ByteBuffer; ...@@ -15,6 +15,7 @@ import java.nio.ByteBuffer;
import java.nio.channels.FileChannel; import java.nio.channels.FileChannel;
import java.nio.channels.FileChannel.MapMode; import java.nio.channels.FileChannel.MapMode;
import java.nio.channels.FileLock; import java.nio.channels.FileLock;
import java.nio.channels.NonWritableChannelException;
import java.sql.Connection; import java.sql.Connection;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
...@@ -549,7 +550,7 @@ public class TestFileSystem extends TestBase { ...@@ -549,7 +550,7 @@ public class TestFileSystem extends TestBase {
fc.write(ByteBuffer.wrap(test, 0, 10)); fc.write(ByteBuffer.wrap(test, 0, 10));
} }
}; };
new AssertThrows(IOException.class) { new AssertThrows(NonWritableChannelException.class) {
@Override @Override
public void test() throws Exception { public void test() throws Exception {
fc.truncate(10); fc.truncate(10);
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论