Note - if my second paragraph above makes no sense, it may be that I'm misinterpreting the assignment, so let me run this part by you. I see in the spec, "the program must allow the user to specify the location of the database, and it must also accept an indication that a local database is to be used..." OK, the latter part is handled by command line arguments defined elsewhere. But does "location of the database" mean "where's the server?" Or does it mean "once we've found the server (or localhost, which ought to be pretty easy if that's what requested) - what's the path to the DB file?" I'm assuming it's the latter, and this this means different clients may connect to different DB files through the same server. But I may be way off here; please let me know.
I still prefer the single FileChannel
As for the latter, the only thing you have to do is lock down the entire db when a create or delete is taking place, say by using a lock(-1). Otherwise, all's well.
File channels are safe for use by multiple concurrent threads. The close method may be invoked at any time, as specified by the Channel interface. Only one operation that involves the channel's position or can change its file's size may be in progress at any given time; attempts to initiate a second such operation while the first is still in progress will block until the first operation completes. Other operations, in particular those that take an explicit position, may proceed concurrently; whether they in fact do so is dependent upon the underlying implementation and is therefore unspecified.
Note that read(ByteBuffer, long) really needs to be called in a loop to ensure that the desired number of bytes is filled - but this isn't a problem.