001    /*
002     * Copyright (C) 2008-2010 by Holger Arndt
003     *
004     * This file is part of the Universal Java Matrix Package (UJMP).
005     * See the NOTICE file distributed with this work for additional
006     * information regarding copyright ownership and licensing.
007     *
008     * UJMP is free software; you can redistribute it and/or modify
009     * it under the terms of the GNU Lesser General Public License as
010     * published by the Free Software Foundation; either version 2
011     * of the License, or (at your option) any later version.
012     *
013     * UJMP is distributed in the hope that it will be useful,
014     * but WITHOUT ANY WARRANTY; without even the implied warranty of
015     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
016     * GNU Lesser General Public License for more details.
017     *
018     * You should have received a copy of the GNU Lesser General Public
019     * License along with UJMP; if not, write to the
020     * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
021     * Boston, MA  02110-1301  USA
022     */
023    
024    package org.ujmp.core.util.io;
025    
026    import java.io.File;
027    import java.io.FileNotFoundException;
028    import java.io.IOException;
029    import java.io.RandomAccessFile;
030    import java.util.Map;
031    
032    import org.ujmp.core.collections.SoftHashMap;
033    
034    public class BufferedRandomAccessFile extends RandomAccessFile {
035    
036            private int bufferSize = 65536;
037    
038            private final Map<Long, byte[]> buffer = new SoftHashMap<Long, byte[]>();
039    
040            public BufferedRandomAccessFile(File file, String mode) throws FileNotFoundException {
041                    super(file, mode);
042            }
043    
044            public BufferedRandomAccessFile(File file, String mode, int bufferSize)
045                            throws FileNotFoundException {
046                    super(file, mode);
047                    this.bufferSize = bufferSize;
048            }
049    
050            
051            public synchronized int read() throws IOException {
052                    byte[] b = new byte[1];
053                    read(b);
054                    seek(getFilePointer() + 1);
055                    new IOException("don't use this method").printStackTrace();
056                    return b[0];
057            }
058    
059            
060            public synchronized void seek(long pos) throws IOException {
061                    new IOException("don't use this method").printStackTrace();
062                    super.seek(pos);
063    
064            }
065    
066            
067            public synchronized int read(byte[] b) throws IOException {
068                    new IOException("don't use this method").printStackTrace();
069                    return super.read(b);
070            }
071    
072            public synchronized int read(long seek, byte b[]) throws IOException {
073                    if (b.length > bufferSize) {
074                            throw (new IOException("cannot read more than buffersize"));
075                    }
076    
077                    long pos = (seek / bufferSize) * bufferSize;
078                    int offset = (int) (seek - pos);
079    
080                    byte[] bytes = buffer.get(pos);
081                    if (bytes == null) {
082                            super.seek(pos);
083                            bytes = new byte[bufferSize];
084                            super.read(bytes);
085                            buffer.put(pos, bytes);
086                    }
087    
088                    if (offset + b.length > bufferSize) {
089                            System.arraycopy(bytes, offset, b, 0, bufferSize - offset);
090                            pos += bufferSize;
091                            bytes = buffer.get(pos);
092                            if (bytes == null) {
093                                    super.seek(pos);
094                                    bytes = new byte[bufferSize];
095                                    super.read(bytes);
096                                    buffer.put(pos, bytes);
097                            }
098                            System.arraycopy(bytes, 0, b, bufferSize - offset, b.length - bufferSize + offset);
099                    } else {
100                            System.arraycopy(bytes, offset, b, 0, b.length);
101                    }
102                    return b.length;
103    
104            }
105    
106            public synchronized void writeByte(long seek, byte value) throws IOException {
107                    super.seek(seek);
108                    super.writeByte(value);
109                    buffer.clear();
110            }
111    
112            public synchronized void writeChar(long seek, char value) throws IOException {
113                    super.seek(seek);
114                    super.writeChar(value);
115                    buffer.clear();
116            }
117    
118            public synchronized void writeDouble(long seek, double value) throws IOException {
119                    super.seek(seek);
120                    super.writeDouble(value);
121                    buffer.clear();
122            }
123    
124            public synchronized void writeFloat(long seek, float value) throws IOException {
125                    super.seek(seek);
126                    super.writeFloat(value);
127                    buffer.clear();
128            }
129    
130            public synchronized void writeShort(long seek, short value) throws IOException {
131                    super.seek(seek);
132                    super.writeShort(value);
133                    buffer.clear();
134            }
135    
136            public synchronized void write(long seek, byte[] array) throws IOException {
137                    super.seek(seek);
138                    super.write(array);
139                    buffer.clear();
140            }
141    
142            public synchronized void writeInt(long seek, int value) throws IOException {
143                    super.seek(seek);
144                    super.writeInt(value);
145                    buffer.clear();
146            }
147    
148            public synchronized void writeLong(long seek, long value) throws IOException {
149                    super.seek(seek);
150                    super.writeLong(value);
151                    buffer.clear();
152            }
153    
154    }