Index: store/fs/FileObjectDiskChannel.java
===================================================================
--- store/fs/FileObjectDiskChannel.java	(revision 0)
+++ store/fs/FileObjectDiskChannel.java	(revision 0)
@@ -0,0 +1,87 @@
+package org.h2.store.fs;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.nio.ByteBuffer;
+import java.nio.channels.FileChannel;
+
+/**
+ * File which uses NIO FileChannel. 
+ *
+ */
+public class FileObjectDiskChannel implements FileObject{
+	
+    private final String name;
+    private FileChannel channel;
+
+    FileObjectDiskChannel(String fileName, String mode) throws FileNotFoundException {
+        this.name = fileName;
+        RandomAccessFile raf =  new RandomAccessFile(fileName,mode);
+        channel = raf.getChannel();
+    }
+
+	public void close() throws IOException {
+		channel.close();		
+	}
+
+	public long getFilePointer() throws IOException {
+		return channel.position();
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public long length() throws IOException {
+		return channel.size();
+	}
+
+	public void readFully(byte[] b, int off, int len) throws IOException {
+		if(len==0)
+			return;			
+		if(channel.size()<=off+len) //TODO get size can degrade performance
+			throw new java.io.EOFException();
+		
+		ByteBuffer buf = ByteBuffer.wrap(b);
+		buf.position(off);
+		buf.limit(off+len);
+		channel.read(buf);
+	}
+
+	public void seek(long pos) throws IOException {
+		//System.out.println("seek");
+		channel.position(pos);	
+	}
+
+	public void setFileLength(long newLength) throws IOException {
+		//System.out.println("setFileLength");
+		//System.out.println(" "+channel.size()+" - "+channel.position());
+		if(newLength<=channel.size()){
+			long oldPos = channel.position();
+			channel.truncate(newLength);
+			if(oldPos>newLength)
+				oldPos = newLength;
+			channel.position(oldPos); 
+		}else{
+			//extend by writting to new location
+			ByteBuffer b = ByteBuffer.allocate(1);
+			channel.write(b, newLength-1);			
+		}				
+		//System.out.println(" "+channel.size()+" - "+channel.position());
+	}
+
+	public void sync() throws IOException {
+		//System.out.println("sync");
+		channel.force(true);
+	}
+
+	public void write(byte[] b, int off, int len) throws IOException {
+		//System.out.println("write");
+		ByteBuffer buf = ByteBuffer.wrap(b);
+		buf.position(off);
+		buf.limit(off+len);		
+		channel.write(buf);		
+	}
+
+}
Index: store/fs/FileObjectDiskMapped.java
===================================================================
--- store/fs/FileObjectDiskMapped.java	(revision 0)
+++ store/fs/FileObjectDiskMapped.java	(revision 0)
@@ -0,0 +1,134 @@
+package org.h2.store.fs;
+
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.lang.ref.WeakReference;
+import java.nio.MappedByteBuffer;
+import java.nio.channels.FileChannel.MapMode;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+import org.h2.util.FileUtils;
+
+
+/**
+ * FileObject which is using NIO MappedByteBuffer mapped to memory from file.
+ * 
+ */
+// TODO support files over 2 GB by using multiple buffers
+// TODO howto dispose MappedByteBuffer? 
+public class FileObjectDiskMapped implements FileObject {
+
+	private static final long GC_TIMEOUT_MS = 10000;
+	private final String name;
+	private RandomAccessFile file;
+	private MappedByteBuffer mapped;
+	private MapMode mode;
+
+	FileObjectDiskMapped(String fileName, String mode) throws IOException {
+		if ("r".equals(mode))
+			this.mode = MapMode.READ_ONLY;
+		else 
+			this.mode = MapMode.READ_WRITE;
+		this.name = fileName;
+		file = new RandomAccessFile(fileName, mode);
+		remap();
+	}
+
+	private void unmap() {
+		if (mapped != null) {
+			//first write all data 
+			mapped.force();
+
+			//need to dispose old Direct buffer, Sun have bug with very long history
+			// http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4724038
+			
+			//this does not work due to security exceptions
+//			try {
+//				Cleaner cleaner = (Cleaner) mapped.getClass().getMethod(
+//						"cleaner").invoke(mapped);
+//				cleaner.clear();
+//			} catch (Exception e) {
+//				throw new RuntimeException("Can not unmap DirectByteBuffer", e);
+//			}
+
+			  WeakReference<MappedByteBuffer> bufferWeakRef = new WeakReference<MappedByteBuffer>(mapped);
+
+			  mapped = null;
+			  long start = System.currentTimeMillis();
+			  while (bufferWeakRef.get() != null) {
+				  if (System.currentTimeMillis() - start > GC_TIMEOUT_MS) {
+					  throw new RuntimeException("Timeout (" + GC_TIMEOUT_MS + " ms) reached while trying to GC mapped buffer");
+				  }
+				  System.gc();
+				  Thread.yield();			
+			  }			 
+		}
+	}
+
+	/**
+	 * remap byte buffer into memory, called when file size has changed or file
+	 * was created
+	 * 
+	 * @throws IOException
+	 */
+	private void remap() throws IOException {
+		if (file.length() > Integer.MAX_VALUE)
+			throw new RuntimeException("File over 2GB is not supported yet");
+		int oldPos = 0;
+		if (mapped != null) {
+			oldPos = mapped.position();
+			mapped.force();
+			unmap();
+		}
+
+		// maps new MappedByteBuffer, old one is disposed during GC
+		mapped = file.getChannel().map(mode, 0, file.length());
+		mapped.position(oldPos);
+	}
+
+	public void close() throws IOException {
+		unmap();
+		
+		file.close();
+		file = null;
+	}
+
+	public long getFilePointer() throws IOException {
+		return mapped.position();
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public long length() throws IOException {
+		return file.length();
+	}
+
+	public void readFully(byte[] b, int off, int len) throws IOException {
+		mapped.get(b, off, len);
+	}
+
+	public void seek(long pos) throws IOException {
+		mapped.position((int) pos);
+	}
+
+	public void setFileLength(long newLength) throws IOException {
+		FileUtils.setLength(file, newLength);
+		remap();
+	}
+
+	public void sync() throws IOException {
+		file.getFD().sync();
+		mapped.force();
+	}
+
+	public void write(byte[] b, int off, int len) throws IOException {
+		// check if need to expand file
+		if (mapped.capacity() < mapped.position() + len)
+			setFileLength(mapped.position() + len);
+		mapped.put(b, off, len);
+	}
+
+}
Index: store/fs/FileSystemDisk.java
===================================================================
--- store/fs/FileSystemDisk.java	(revision 1275)
+++ store/fs/FileSystemDisk.java	(working copy)
@@ -367,19 +367,47 @@
 
     public FileObject openFileObject(String fileName, String mode) throws IOException {
         fileName = translateFileName(fileName);
-        FileObjectDisk f;
+        FileObject f;
+//        try {
+//            f = new FileObjectDiskChannel(fileName, mode);
+//            trace("openRandomAccessFile", fileName, f);
+//        } catch (IOException e) {
+//            freeMemoryAndFinalize();
+//            try {
+//                f = new FileObjectDiskChannel(fileName, mode);
+//            } catch (IOException e2) {
+//                e2.initCause(e);
+//                throw e2;
+//            }
+//        }
+
         try {
-            f = new FileObjectDisk(fileName, mode);
+            f = new FileObjectDiskMapped(fileName, mode);
             trace("openRandomAccessFile", fileName, f);
         } catch (IOException e) {
             freeMemoryAndFinalize();
             try {
-                f = new FileObjectDisk(fileName, mode);
+                f = new FileObjectDiskMapped(fileName, mode);
             } catch (IOException e2) {
                 e2.initCause(e);
                 throw e2;
             }
         }
+
+        
+//        try {
+//            f = new FileObjectDisk(fileName, mode);
+//            trace("openRandomAccessFile", fileName, f);
+//        } catch (IOException e) {
+//            freeMemoryAndFinalize();
+//            try {
+//                f = new FileObjectDisk(fileName, mode);
+//            } catch (IOException e2) {
+//                e2.initCause(e);
+//                throw e2;
+//            }
+//        }
+
         return f;
     }
 
Index: util/FileUtils.java
===================================================================
--- util/FileUtils.java	(revision 1275)
+++ util/FileUtils.java	(working copy)
@@ -268,6 +268,8 @@
      */
     public static void delete(String fileName) throws SQLException {
         FileSystem.getInstance(fileName).delete(fileName);
+        if(FileSystem.getInstance(fileName).exists(fileName))
+        	throw new RuntimeException("File was not deleted "+fileName);
     }
 
     /**
