Pluggable IO Concept

Db4o input/output implementation comes as a pluggable module. It means that you can write your own IO system based on IoAdapter class.

Pluggable IO Adapter has control over the following:

Some of the popular implementations of IoAdapter:

You can look at the db4o source to see some of these implementations (search for classes inheriting from IoAdapter).

By default db4o uses RandomAccessFileAdapter. You can install another IoAdapter with a single call:

Java: Db4o.configure().io(new SpecificIoAdapter())

Please, note: this call should be issued before opening of a database file. IoAdapter can be changed only while the database is closed.

For a test, let's try to create debugging IoAdapter, which will log all the information about its actions to the output stream:

LoggingAdapter.java
001/* Copyright (C) 2004 - 2006 db4objects Inc. http://www.db4o.com */ 002 003package com.db4odoc.ios; 004 005import java.io.File; 006import java.io.IOException; 007import java.io.PrintStream; 008import java.io.RandomAccessFile; 009 010import com.db4o.DTrace; 011import com.db4o.ext.DatabaseFileLockedException; 012import com.db4o.internal.*; 013import com.db4o.io.IoAdapter; 014 015public class LoggingAdapter extends IoAdapter { 016 017 private String _path; 018 private RandomAccessFile _delegate; 019 private PrintStream _out = System.out; 020 021 public LoggingAdapter(){ 022 } 023 024 protected LoggingAdapter(String path, boolean lockFile, long initialLength) throws IOException { 025 _path=new File(path).getCanonicalPath(); 026 _delegate = new RandomAccessFile(path, "rw"); 027 if(initialLength>0) { 028 _delegate.seek(initialLength - 1); 029 _delegate.write(new byte[] {0}); 030 } 031 if(lockFile){ 032 try { 033 Platform4.lockFile(_path, _delegate); 034 } catch (DatabaseFileLockedException e) { 035 _delegate.close(); 036 throw e; 037 } 038 } 039 } 040 041 public void setOut(PrintStream out){ 042 _out = out; 043 } 044 045 public void close() throws IOException { 046 _out.println("Closing file"); 047 try { 048 Platform4.unlockFile(_path,_delegate); 049 } catch (Exception e) { 050 } 051 _delegate.close(); 052 } 053 054 055 public void delete(String path) { 056 _out.println("Deleting file " + path); 057 new File(path).delete(); 058 } 059 060 public boolean exists(String path){ 061 File existingFile = new File(path); 062 return existingFile.exists() && existingFile.length() > 0; 063 } 064 065 public long getLength() throws IOException { 066 _out.println("File length:" + _delegate.length()); 067 return _delegate.length(); 068 } 069 070 public IoAdapter open(String path, boolean lockFile, long initialLength) throws IOException { 071 _out.println("Opening file " + path); 072 return new LoggingAdapter(path, lockFile, initialLength); 073 } 074 075 076 public int read(byte[] bytes, int length) throws IOException { 077 _out.println("Reading " + length + " bytes"); 078 return _delegate.read(bytes, 0, length); 079 } 080 081 082 public void seek(long pos) throws IOException { 083 084 if(DTrace.enabled){ 085 DTrace.REGULAR_SEEK.log(pos); 086 } 087 _out.println("Setting pointer position to " + pos); 088 _delegate.seek(pos); 089 } 090 091 092 public void sync() throws IOException { 093 _out.println("Synchronizing"); 094 _delegate.getFD().sync(); 095 } 096 097 098 public void write(byte[] buffer, int length) throws IOException { 099 _out.println("Writing " + length + " bytes"); 100 _delegate.write(buffer, 0, length); 101 102 } 103 104}

Now let's test how it works:

IOExample.java: testLoggingAdapter
01public static void testLoggingAdapter(){ 02 Db4o.configure().io(new LoggingAdapter()); 03 ObjectContainer db = Db4o.openFile(YAPFILENAME); 04 try { 05 Pilot pilot = new Pilot("Michael Schumacher"); 06 db.set(pilot); 07 System.out.println("New pilot added"); 08 } finally { 09 db.close(); 10 } 11 12 db = Db4o.openFile(YAPFILENAME); 13 try { 14 ObjectSet result=db.get(Pilot.class); 15 listResult(result); 16 } finally { 17 db.close(); 18 } 19 Db4o.configure().io(new RandomAccessFileAdapter()); 20 }

The output can be used for debugging purposes.