Statistics
| Revision:

svn-gvsig-desktop / tags / v1_0_2_Build_892 / libraries / libIverUtiles / src / com / iver / utiles / bigfile / BigByteBuffer.java @ 10278

History | View | Annotate | Download (9.26 KB)

1 2459 fjp
/*
2
 * Created on 11-jul-2005
3
 *
4
 * gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
5
 *
6
 * Copyright (C) 2004 IVER T.I. and Generalitat Valenciana.
7
 *
8
 * This program is free software; you can redistribute it and/or
9
 * modify it under the terms of the GNU General Public License
10
 * as published by the Free Software Foundation; either version 2
11
 * of the License, or (at your option) any later version.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU General Public License
19
 * along with this program; if not, write to the Free Software
20
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
21
 *
22
 * For more information, contact:
23
 *
24
 *  Generalitat Valenciana
25
 *   Conselleria d'Infraestructures i Transport
26
 *   Av. Blasco Ib??ez, 50
27
 *   46010 VALENCIA
28
 *   SPAIN
29
 *
30
 *      +34 963862235
31
 *   gvsig@gva.es
32
 *      www.gvsig.gva.es
33
 *
34
 *    or
35
 *
36
 *   IVER T.I. S.A
37
 *   Salamanca 50
38
 *   46005 Valencia
39
 *   Spain
40
 *
41
 *   +34 963163400
42
 *   dac@iver.es
43
 */
44
package com.iver.utiles.bigfile;
45
46
import java.io.IOException;
47
import java.nio.Buffer;
48
import java.nio.ByteBuffer;
49
import java.nio.ByteOrder;
50
import java.nio.CharBuffer;
51
import java.nio.DoubleBuffer;
52
import java.nio.FloatBuffer;
53
import java.nio.IntBuffer;
54
import java.nio.LongBuffer;
55
import java.nio.MappedByteBuffer;
56
import java.nio.ShortBuffer;
57
import java.nio.channels.FileChannel;
58
59
/**
60
 * @author Fjp
61
 *
62
 * Clase para trabajar con ficheros grandes. Mapea solo un trozo
63
 * de fichero en memoria, y cuando intentas acceder fuera de esa
64
 * zona, se ocupa de leer autom?ticamente el trozo que le falta.
65
 */
66
public class BigByteBuffer {
67
68
    private static long DEFAULT_SIZE = 50*1024*1024; // 50 Megas m?ximo
69
70
    MappedByteBuffer bb;
71
    FileChannel fc;
72
    long minAbs, maxAbs, posAbs;
73
    int minRel,  maxRel, posRel;
74
    long sizeChunk, amountMem;
75
    long fileSize;
76
    FileChannel.MapMode mode;
77
78
    /**
79
     * Revisa la posici?n absoluta, y si hace falta, carga el buffer
80
     * con la parte de fichero que toca.
81
     * @throws IOException
82
     */
83
    private void prepareBuffer(long posActual, int numBytesToRead)
84
    {
85
        long desiredPos = posActual + numBytesToRead;
86
        if ((desiredPos > maxAbs) || (posActual < minAbs))
87
        {
88
            // Quiero leer fuera:
89
            sizeChunk = Math.min(fileSize-posActual, amountMem);
90
            try {
91
                ByteOrder lastOrder = bb.order();
92
                bb = fc.map(mode, posActual, sizeChunk);
93
                minAbs = posActual;
94
                maxAbs = sizeChunk + posActual;
95
                bb.order(lastOrder);
96
                // System.out.println("BigByteBuffer: min=" + minAbs
97
                //     + " maxAbs=" + maxAbs + " posAbs = " + posAbs);
98
99
            } catch (IOException e) {
100
                // TODO Auto-generated catch block
101
                e.printStackTrace();
102
            }
103
104
        }
105
        // Dejamos posAbs apuntando a donde va a quedar
106
        // "a priori", antes de leer de verdad, que se hace
107
        // al salir de esta funci?n.
108
        posAbs = desiredPos;
109
110
    }
111
112
    public BigByteBuffer(FileChannel fc, FileChannel.MapMode mode, long amountMem) throws IOException
113
    {
114
        this.amountMem = amountMem;
115
        this.fc = fc;
116
        this.fileSize = fc.size();
117
        this.mode = mode;
118
        sizeChunk = Math.min(fc.size(), amountMem);
119
        bb = fc.map(mode, 0L, sizeChunk);
120
        minAbs = 0;
121
        maxAbs = sizeChunk;
122
    }
123
    public BigByteBuffer(FileChannel fc, FileChannel.MapMode mode) throws IOException
124
    {
125
        this.amountMem = DEFAULT_SIZE;
126
        this.fc = fc;
127
        this.fileSize = fc.size();
128
        this.mode = mode;
129
        sizeChunk = Math.min(fc.size(), amountMem);
130
        bb = fc.map(mode, 0L, sizeChunk);
131
        minAbs = 0;
132
        maxAbs = sizeChunk;
133
    }
134
135
136 3080 fjp
    public synchronized byte get() {
137 2459 fjp
        prepareBuffer(posAbs,1);
138
        return bb.get();
139
    }
140 3080 fjp
    public synchronized ByteBuffer get(byte[] dst)
141 2459 fjp
    {
142
        prepareBuffer(posAbs, dst.length);
143
        return bb.get(dst);
144
    }
145
146 3080 fjp
    public synchronized char getChar() {
147 2459 fjp
        prepareBuffer(posAbs,2);
148
        return bb.getChar();
149
    }
150
151 3080 fjp
    public synchronized double getDouble() {
152 2459 fjp
        prepareBuffer(posAbs,8);
153
        return bb.getDouble();
154
    }
155
156 3080 fjp
    public synchronized float getFloat() {
157 2459 fjp
        prepareBuffer(posAbs,4);
158
        return bb.getFloat();
159
    }
160
161 3080 fjp
    public synchronized int getInt() {
162 2459 fjp
        prepareBuffer(posAbs,4);
163
        return bb.getInt();
164
    }
165
166 3080 fjp
    public synchronized long getLong() {
167 2459 fjp
        prepareBuffer(posAbs,8);
168
        return bb.getLong();
169
    }
170
171 3080 fjp
    public synchronized short getShort() {
172 2459 fjp
        prepareBuffer(posAbs,2);
173
        return bb.getShort();
174
    }
175
176
    public boolean isDirect() {
177
        return bb.isDirect();
178
    }
179
180 3080 fjp
    public synchronized byte get(int index) {
181 2459 fjp
        prepareBuffer(index,1);
182
        return bb.get(index - (int) minAbs);
183
    }
184
185 3080 fjp
    public synchronized char getChar(int index) {
186 2459 fjp
        prepareBuffer(index,2);
187
        return bb.getChar(index - (int) minAbs);
188
    }
189
190 3080 fjp
    public synchronized double getDouble(int index) {
191 2459 fjp
        prepareBuffer(index,8);
192
        return bb.getDouble(index - (int) minAbs);
193
    }
194
195 3080 fjp
    public synchronized float getFloat(int index) {
196 2459 fjp
        prepareBuffer(index,4);
197
        return bb.getFloat(index - (int) minAbs);
198
    }
199
200 3080 fjp
    public synchronized int getInt(int index) {
201 2459 fjp
        prepareBuffer(index,4);
202
        return bb.getInt(index - (int) minAbs);
203
    }
204
205 3080 fjp
    public synchronized long getLong(int index) {
206 2459 fjp
        prepareBuffer(index,8);
207
        return bb.getLong(index - (int) minAbs);
208
    }
209
210 3080 fjp
    public synchronized short getShort(int index) {
211 2459 fjp
        prepareBuffer(index,2);
212
        return bb.getShort(index - (int) minAbs);
213
    }
214
215 2673 fjp
    public ByteBuffer asReadOnlyBuffer() {
216 2459 fjp
        return bb.asReadOnlyBuffer();
217
    }
218
219
    public ByteBuffer compact() {
220
        return bb.compact();
221
    }
222
223
    public ByteBuffer duplicate() {
224
        return bb.duplicate();
225
    }
226
227
    public ByteBuffer slice() {
228
        return bb.slice();
229
    }
230
231 3080 fjp
    public synchronized ByteBuffer put(byte b) {
232 2459 fjp
        prepareBuffer(posAbs,1);
233
        return bb.put(b);
234
    }
235
236 3080 fjp
    public synchronized ByteBuffer putChar(char value) {
237 2459 fjp
        prepareBuffer(posAbs,2);
238
        return bb.putChar(value);
239
    }
240
241 3080 fjp
    public synchronized ByteBuffer putDouble(double value) {
242 2459 fjp
        prepareBuffer(posAbs,8);
243
        return bb.putDouble(value);
244
    }
245
246 3080 fjp
    public synchronized ByteBuffer putFloat(float value) {
247 2459 fjp
        prepareBuffer(posAbs,4);
248
        return bb.putFloat(value);
249
    }
250
251 3080 fjp
    public synchronized ByteBuffer putInt(int value) {
252 2459 fjp
        prepareBuffer(posAbs,4);
253
        return bb.putInt(value);
254
    }
255
256 3080 fjp
    public synchronized ByteBuffer put(int index, byte b) {
257 2459 fjp
        prepareBuffer(index,1);
258
        return bb.put(index- (int) minAbs, b);
259
    }
260
261 3080 fjp
    public synchronized ByteBuffer putChar(int index, char value) {
262 2459 fjp
        prepareBuffer(index,2);
263
        return bb.putChar(index- (int) minAbs, value);
264
    }
265
266 3080 fjp
    public synchronized ByteBuffer putDouble(int index, double value) {
267 2459 fjp
        prepareBuffer(index,8);
268
        return bb.putDouble(index- (int) minAbs, value);
269
    }
270
271 3080 fjp
    public synchronized ByteBuffer putFloat(int index, float value) {
272 2459 fjp
        prepareBuffer(index,4);
273
        return bb.putFloat(index- (int) minAbs, value);
274
    }
275
276 3080 fjp
    public synchronized ByteBuffer putInt(int index, int value) {
277 2459 fjp
        prepareBuffer(index,4);
278
        return bb.putInt(index- (int) minAbs, value);
279
    }
280
281 3080 fjp
    public synchronized ByteBuffer putLong(int index, long value) {
282 2459 fjp
        prepareBuffer(index,8);
283
        return bb.putLong(index- (int) minAbs, value);
284
    }
285
286 3080 fjp
    public synchronized ByteBuffer putShort(int index, short value) {
287 2459 fjp
        prepareBuffer(index,2);
288
        return bb.putShort(index- (int) minAbs, value);
289
    }
290
291 3080 fjp
    public synchronized ByteBuffer putLong(long value) {
292 2459 fjp
        prepareBuffer(posAbs,8);
293
        return bb.putLong(value);
294
    }
295
296 3080 fjp
    public synchronized ByteBuffer putShort(short value) {
297 2459 fjp
        prepareBuffer(posAbs,2);
298
        return bb.putShort(value);
299
    }
300
301
    public CharBuffer asCharBuffer() {
302
        return bb.asCharBuffer();
303
    }
304
305
    public DoubleBuffer asDoubleBuffer() {
306
        return bb.asDoubleBuffer();
307
    }
308
309
    public FloatBuffer asFloatBuffer() {
310
        return bb.asFloatBuffer();
311
    }
312
313
    public IntBuffer asIntBuffer() {
314
        return bb.asIntBuffer();
315
    }
316
317
    public LongBuffer asLongBuffer() {
318
        return bb.asLongBuffer();
319
    }
320
321
    public ShortBuffer asShortBuffer() {
322
        return bb.asShortBuffer();
323
    }
324
325
    public boolean isReadOnly() {
326
        return bb.isReadOnly();
327
    }
328
329
    public final ByteOrder order()
330
    {
331
        return bb.order();
332
    }
333
334
    public final ByteBuffer order(ByteOrder bo)
335
    {
336
        return bb.order(bo);
337
    }
338
    public final long position()
339
    {
340
        return posAbs;
341
    }
342
343 3080 fjp
    public synchronized final Buffer position(long newPosition)
344 2459 fjp
    {
345
        prepareBuffer(newPosition,0);
346
        int relPos = (int) (newPosition - minAbs);
347
        // System.out.println("Position=" + newPosition);
348
        return bb.position(relPos);
349
    }
350
351
}