/** * */ package com.jmatio.io.stream; import java.io.File; import java.io.IOException; import java.io.OutputStream; import java.io.RandomAccessFile; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; import com.jmatio.types.MLArray; /** * This is an {@link OutputStream} that is backed by a {@link RandomAccessFile} * and accessed with buffered access. * * @author Wojciech Gradkowski (wgradkowski@gmail.com) * */ public class FileBufferedOutputStream extends BufferedOutputStream { private static final int BUFFER_SIZE = 1024; private ByteBuffer buf; private FileChannel rwChannel; private RandomAccessFile raFile; private final File file; public FileBufferedOutputStream() throws IOException { file = File.createTempFile( "jmatio-", null ); file.deleteOnExit(); raFile = new RandomAccessFile(file, "rw"); rwChannel = raFile.getChannel(); buf = ByteBuffer.allocate( BUFFER_SIZE ); } public FileBufferedOutputStream( MLArray array ) throws IOException { file = File.createTempFile( "jmatio-" + array.getName() + "-", null ); file.deleteOnExit(); raFile = new RandomAccessFile(file, "rw"); rwChannel = raFile.getChannel(); buf = ByteBuffer.allocate( BUFFER_SIZE ); } @Override public void write(int b) throws IOException { if ( buf.position() >= buf.capacity() ) { flush(); } buf.put( (byte) (b & 0xff) ); } /* (non-Javadoc) * @see java.io.OutputStream#write(byte[]) */ @Override public void write(byte[] b) throws IOException { write(b, 0, b.length); } /* (non-Javadoc) * @see java.io.OutputStream#write(byte[], int, int) */ @Override public void write(byte[] b, int off, int len) throws IOException { int wbytes = len; int offset = off; while( wbytes > 0 ) { if ( buf.position() >= buf.capacity() ) { flush(); } int length = Math.min( wbytes, buf.limit() - buf.position() ); buf.put(b, offset, length); offset += length; wbytes -= length; } } /* (non-Javadoc) * @see java.io.OutputStream#close() */ @Override public void close() throws IOException { flush(); buf = null; if ( rwChannel.isOpen() ) { rwChannel.close(); } raFile.close(); rwChannel = null; raFile = null; } /* (non-Javadoc) * @see java.io.OutputStream#flush() */ @Override public void flush() throws IOException { if ( buf != null && buf.position() > 0 ) { buf.flip(); rwChannel.write( buf ); buf.clear(); } } /* (non-Javadoc) * @see com.jmatio.io.DataOutputStream#size() */ public long size() throws IOException { flush(); return (int) file.length(); } /* (non-Javadoc) * @see com.jmatio.io.DataOutputStream#getByteBuffer() */ @Override public ByteBuffer buffer() throws IOException { return rwChannel.map( FileChannel.MapMode.READ_ONLY, 0, file.length() ); } /* (non-Javadoc) * @see com.jmatio.io.DataOutputStream#write(java.nio.ByteBuffer) */ public void write( ByteBuffer byteBuffer ) throws IOException { byte[] tmp = new byte[BUFFER_SIZE]; while ( byteBuffer.hasRemaining() ) { int length = Math.min( byteBuffer.remaining(), tmp.length ); byteBuffer.get( tmp, 0, length); write(tmp, 0, length); } } }