diff --git oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/OakDirectory.java oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/OakDirectory.java
index 8256394..2875649 100644
--- oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/OakDirectory.java
+++ oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/OakDirectory.java
@@ -30,6 +30,8 @@ import org.apache.jackrabbit.oak.api.Blob;
 import org.apache.jackrabbit.oak.api.PropertyState;
 import org.apache.jackrabbit.oak.api.Type;
 import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
+import org.apache.lucene.store.BufferedIndexInput;
+import org.apache.lucene.store.BufferedIndexOutput;
 import org.apache.lucene.store.Directory;
 import org.apache.lucene.store.IOContext;
 import org.apache.lucene.store.IndexInput;
@@ -153,6 +155,7 @@ class OakDirectory extends Directory {
     static final int DEFAULT_BLOB_SIZE = 32 * 1024;
 
     private static class OakIndexFile {
+        private final boolean isReadOnly;
 
         private final String name;
 
@@ -174,7 +177,10 @@ class OakDirectory extends Directory {
 
         private boolean blobModified = false;
 
-        public OakIndexFile(String name, NodeBuilder file) {
+        private volatile boolean isOpen = true;
+
+        public OakIndexFile(String name, NodeBuilder file, boolean isReadOnly) {
+            this.isReadOnly = isReadOnly;
             this.name = name;
             this.file = file;
             this.blobSize = determineBlobSize(file);
@@ -195,6 +201,7 @@ class OakDirectory extends Directory {
         }
 
         private OakIndexFile(OakIndexFile that) {
+            this.isReadOnly = that.isReadOnly;
             this.name = that.name;
             this.file = that.file;
             this.blobSize = that.blobSize;
@@ -225,6 +232,7 @@ class OakDirectory extends Directory {
 
         private void flushBlob() throws IOException {
             if (blobModified) {
+                checkState(!isReadOnly);
                 int n = (int) Math.min(blobSize, length - index * blobSize);
                 Blob b = file.createBlob(new ByteArrayInputStream(blob, 0, n));
                 if (index < data.size()) {
@@ -303,6 +311,16 @@ class OakDirectory extends Directory {
             }
         }
 
+        void close() throws IOException {
+            if (isOpen) {
+                if (!isReadOnly) {
+                    flush();
+                }
+                data.clear();
+                isOpen = false;
+            }
+        }
+
         private static int determineBlobSize(NodeBuilder file){
             if (file.hasProperty(PROP_BLOB_SIZE)){
                 return Ints.checkedCast(file.getProperty(PROP_BLOB_SIZE).getValue(Type.LONG));
@@ -326,13 +344,12 @@ class OakDirectory extends Directory {
 
     }
 
-    private static class OakIndexInput extends IndexInput {
-
+    private static class OakIndexInput extends BufferedIndexInput {
         private final OakIndexFile file;
 
         public OakIndexInput(String name, NodeBuilder file) {
             super(name);
-            this.file = new OakIndexFile(name, file);
+            this.file = new OakIndexFile(name, file, true);
         }
 
         private OakIndexInput(OakIndexInput that) {
@@ -346,45 +363,31 @@ class OakDirectory extends Directory {
         }
 
         @Override
-        public void readBytes(byte[] b, int o, int n) throws IOException {
-            file.readBytes(b, o, n);
+        protected void readInternal(byte[] b, int offset, int length) throws IOException {
+            file.readBytes(b, offset, length);
         }
 
         @Override
-        public byte readByte() throws IOException {
-            byte[] b = new byte[1];
-            readBytes(b, 0, 1);
-            return b[0];
+        protected void seekInternal(long pos) throws IOException {
+            file.seek(pos);
         }
 
         @Override
-        public void seek(long pos) throws IOException {
-            file.seek(pos);
+        public void close() throws IOException {
+            file.close();
         }
 
         @Override
         public long length() {
             return file.length;
         }
-
-        @Override
-        public long getFilePointer() {
-            return file.position;
-        }
-
-        @Override
-        public void close() {
-            // do nothing
-        }
-
     }
 
-    private final class OakIndexOutput extends IndexOutput {
-
+    private final class OakIndexOutput extends BufferedIndexOutput {
         private final OakIndexFile file;
 
         public OakIndexOutput(String name, NodeBuilder file) throws IOException {
-            this.file = new OakIndexFile(name, file);
+            this.file = new OakIndexFile(name, file, false);
         }
 
         @Override
@@ -393,36 +396,16 @@ class OakDirectory extends Directory {
         }
 
         @Override
-        public long getFilePointer() {
-            return file.position;
-        }
-
-        @Override
-        public void seek(long pos) throws IOException {
-            file.seek(pos);
-        }
-
-        @Override
-        public void writeBytes(byte[] b, int offset, int length)
-                throws IOException {
-            file.writeBytes(b, offset, length);
-        }
-
-        @Override
-        public void writeByte(byte b) throws IOException {
-            writeBytes(new byte[] { b }, 0, 1);
-        }
-
-        @Override
-        public void flush() throws IOException {
+        protected void flushBuffer(byte[] b, int offset, int len) throws IOException {
+            file.writeBytes(b, offset, len);
             file.flush();
         }
 
         @Override
         public void close() throws IOException {
-            flush();
+            super.close();
+            file.close();
         }
-
     }
 
 }
