FileDocCategorySizeDatePackage
MappedFileTokenizer.javaAPI DocExample2793Sat Jan 24 10:44:28 GMT 2004je3.nio

MappedFileTokenizer.java

/*
 * Copyright (c) 2004 David Flanagan.  All rights reserved.
 * This code is from the book Java Examples in a Nutshell, 3nd Edition.
 * It is provided AS-IS, WITHOUT ANY WARRANTY either expressed or implied.
 * You may study, use, and modify it for any non-commercial purpose,
 * including teaching and use in open-source projects.
 * You may distribute it non-commercially as long as you retain this notice.
 * For a commercial use license, or to purchase the book, 
 * please visit http://www.davidflanagan.com/javaexamples3.
 */
package je3.nio;
import java.io.*;
import java.nio.*;
import java.nio.channels.*;
import java.nio.charset.*;

/**
 * This class implements the Tokenizer interface for a FileChannel and Charset.
 * It extends ByteBufferTokenizer and uses FileChannel.map() to memory-map the
 * contents of the file into a ByteBuffer.
 */
public class MappedFileTokenizer extends ByteBufferTokenizer {
    static final int DEFAULT_BUFFER_SIZE = 32*1024;
    FileChannel channel;    // The file we want to tokenize
    int byteBufferSize;     // What size chunks to map at at time
    long filesize;          // How big the file is
    long fileposition;      // Starting position of the next chunk

    // Construct a tokenizer for the specified FileChannel, assuming the
    // file contains text encoded using the specified Charset.
    public MappedFileTokenizer(FileChannel channel, Charset charset)
	throws IOException
    {
	this(channel, charset, DEFAULT_BUFFER_SIZE, DEFAULT_BUFFER_SIZE);
    }

    // Construct a tokenizer for the specified file and charset, additionally
    // specifying the size of the byte and characters buffers to use.
    public MappedFileTokenizer(FileChannel channel, Charset charset,
			       int charBufferSize, int byteBufferSize)
	throws IOException
    {
	super(charset, charBufferSize); // Superclass handles charset and size
	this.channel = channel;
	this.byteBufferSize = byteBufferSize; 
	filesize = channel.size();      // Get the length of the file
	fileposition = 0;               // And start at the beginning
    }

    // Return true if there are more bytes for us to return
    protected boolean hasMoreBytes() { return fileposition < filesize; }

    // Read the next chunk of bytes and return them.
    protected ByteBuffer getMoreBytes() throws IOException {
	// Return byteBufferSize bytes, or the number remaining in the file
	// if that is less
	long length = byteBufferSize;
	if (fileposition + length > filesize) length = filesize-fileposition;

	// Memory map the bytes into a buffer
	ByteBuffer buffer =
	    channel.map(FileChannel.MapMode.READ_ONLY, fileposition, length);
	// Store the position of the next chunk
	fileposition += length;
	// And return the memory-mapped buffer of bytes.
	return buffer;
    }
}