Statistics
| Revision:

root / trunk / libraries / libIverUtiles / src / com / iver / utiles / bigfile / BigByteBuffer2.java @ 29011

History | View | Annotate | Download (10 KB)

1
/*
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.ShortBuffer;
56
import java.nio.channels.FileChannel;
57

    
58
/**
59
 * @author Fjp
60
 *
61
 * Clase para trabajar con ficheros grandes. Mapea solo un trozo
62
 * de fichero en memoria, y cuando intentas acceder fuera de esa
63
 * zona, se ocupa de leer autom?ticamente el trozo que le falta.
64
 */
65
public class BigByteBuffer2 {
66

    
67
        private static long DEFAULT_SIZE = 60*1024; // 60 Kbytes
68

    
69
    ByteBuffer bb;
70
    // byte[] buff = new byte[1024 * 1024];;
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 synchronized 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
                mapFrom(posActual);
92
                // System.out.println("BigByteBuffer: min=" + minAbs
93
                //     + " maxAbs=" + maxAbs + " posAbs = " + posAbs);
94

    
95
            } catch (IOException e) {
96
                e.printStackTrace();
97

    
98
            }
99

    
100
        }
101
        // Dejamos posAbs apuntando a donde va a quedar
102
        // "a priori", antes de leer de verdad, que se hace
103
        // al salir de esta funci?n.
104
        posAbs = desiredPos;
105

    
106
    }
107

    
108
    /**
109
     * @param posActual
110
     * @throws IOException
111
     */
112
    private synchronized ByteBuffer mapFrom(long newPos) throws IOException {
113
        ByteOrder lastOrder = bb.order();
114
        // bb = fc.map(mode, newPos, sizeChunk);
115
        fc.position(newPos);
116
        // bb = ByteBuffer.wrap(buff);
117
        // bb = ByteBuffer.allocate((int)sizeChunk);
118
        bb.position(0);
119
        int numRead = fc.read(bb);
120
        bb.position(0);
121
        // System.out.println("Mapeo desde " + newPos + " con sizeChunk= " + sizeChunk + " numRead = " + numRead);
122
        minAbs = newPos;
123
        maxAbs = sizeChunk + newPos;
124
        bb.order(lastOrder);
125
        return bb;
126
    }
127

    
128
    public BigByteBuffer2(FileChannel fc, FileChannel.MapMode mode, long amountMem) throws IOException
129
    {
130
        this.amountMem = amountMem;
131
        // this.buff = new byte[(int) amountMem];
132
        this.fc = fc;
133
        this.fileSize = fc.size();
134
        this.mode = mode;
135
        sizeChunk = Math.min(fc.size(), amountMem);
136
        // bb = fc.map(mode, 0L, sizeChunk);
137
        // bb = ByteBuffer.wrap(buff);
138
        bb = ByteBuffer.allocateDirect((int)sizeChunk);
139
        int numRead = fc.read(bb);
140
        bb.position(0);
141
        minAbs = 0;
142
        maxAbs = sizeChunk;
143
    }
144
    public BigByteBuffer2(FileChannel fc, FileChannel.MapMode mode) throws IOException
145
    {
146
        this.amountMem = DEFAULT_SIZE;
147
        this.fc = fc;
148
        this.fileSize = fc.size();
149
        this.mode = mode;
150
        sizeChunk = Math.min(fc.size(), amountMem);
151
        // bb = fc.map(mode, 0L, sizeChunk);
152
        bb = ByteBuffer.allocateDirect((int)sizeChunk);
153
        int numRead = fc.read(bb);
154
        bb.position(0);
155
        minAbs = 0;
156
        maxAbs = sizeChunk;
157
    }
158

    
159

    
160
    public synchronized byte get() {
161
        prepareBuffer(posAbs,1);
162
        return bb.get();
163
    }
164
    public synchronized ByteBuffer get(byte[] dst)
165
    {
166
        prepareBuffer(posAbs, dst.length);
167
        return bb.get(dst);
168
    }
169

    
170
    public synchronized char getChar() {
171
        prepareBuffer(posAbs,2);
172
        return bb.getChar();
173
    }
174

    
175
    public synchronized double getDouble() {
176
        prepareBuffer(posAbs,8);
177
        return bb.getDouble();
178
    }
179

    
180
    public synchronized float getFloat() {
181
        prepareBuffer(posAbs,4);
182
        return bb.getFloat();
183
    }
184

    
185
    public synchronized int getInt() {
186
        prepareBuffer(posAbs,4);
187
        return bb.getInt();
188
    }
189

    
190
    public synchronized long getLong() {
191
        prepareBuffer(posAbs,8);
192
        return bb.getLong();
193
    }
194

    
195
    public synchronized short getShort() {
196
        prepareBuffer(posAbs,2);
197
        return bb.getShort();
198
    }
199

    
200
    public boolean isDirect() {
201
        return bb.isDirect();
202
    }
203

    
204
    public synchronized byte get(int index) {
205
        prepareBuffer(index,1);
206
        return bb.get(index - (int) minAbs);
207
    }
208

    
209
    public synchronized char getChar(int index) {
210
        prepareBuffer(index,2);
211
        return bb.getChar(index - (int) minAbs);
212
    }
213

    
214
    public synchronized double getDouble(int index) {
215
        prepareBuffer(index,8);
216
        return bb.getDouble(index - (int) minAbs);
217
    }
218

    
219
    public synchronized float getFloat(int index) {
220
        prepareBuffer(index,4);
221
        return bb.getFloat(index - (int) minAbs);
222
    }
223

    
224
    public synchronized int getInt(int index) {
225
        prepareBuffer(index,4);
226
        return bb.getInt(index - (int) minAbs);
227
    }
228

    
229
    public synchronized long getLong(int index) {
230
        prepareBuffer(index,8);
231
        return bb.getLong(index - (int) minAbs);
232
    }
233

    
234
    public synchronized short getShort(int index) {
235
        prepareBuffer(index,2);
236
        return bb.getShort(index - (int) minAbs);
237
    }
238

    
239
    public ByteBuffer asReadOnlyBuffer() {
240
        return bb.asReadOnlyBuffer();
241
    }
242

    
243
    public ByteBuffer compact() {
244
        return bb.compact();
245
    }
246

    
247
    public ByteBuffer duplicate() {
248
        return bb.duplicate();
249
    }
250

    
251
    public synchronized ByteBuffer slice() {
252
        return bb.slice();
253
    }
254

    
255
    public synchronized ByteBuffer put(byte b) {
256
        prepareBuffer(posAbs,1);
257
        return bb.put(b);
258
    }
259

    
260
    public synchronized ByteBuffer putChar(char value) {
261
        prepareBuffer(posAbs,2);
262
        return bb.putChar(value);
263
    }
264

    
265
    public synchronized ByteBuffer putDouble(double value) {
266
        prepareBuffer(posAbs,8);
267
        return bb.putDouble(value);
268
    }
269

    
270
    public synchronized ByteBuffer putFloat(float value) {
271
        prepareBuffer(posAbs,4);
272
        return bb.putFloat(value);
273
    }
274

    
275
    public synchronized ByteBuffer putInt(int value) {
276
        prepareBuffer(posAbs,4);
277
        return bb.putInt(value);
278
    }
279

    
280
    public synchronized ByteBuffer put(int index, byte b) {
281
        prepareBuffer(index,1);
282
        return bb.put(index- (int) minAbs, b);
283
    }
284

    
285
    public synchronized ByteBuffer putChar(int index, char value) {
286
        prepareBuffer(index,2);
287
        return bb.putChar(index- (int) minAbs, value);
288
    }
289

    
290
    public synchronized ByteBuffer putDouble(int index, double value) {
291
        prepareBuffer(index,8);
292
        return bb.putDouble(index- (int) minAbs, value);
293
    }
294

    
295
    public synchronized ByteBuffer putFloat(int index, float value) {
296
        prepareBuffer(index,4);
297
        return bb.putFloat(index- (int) minAbs, value);
298
    }
299

    
300
    public synchronized ByteBuffer putInt(int index, int value) {
301
        prepareBuffer(index,4);
302
        return bb.putInt(index- (int) minAbs, value);
303
    }
304

    
305
    public synchronized ByteBuffer putLong(int index, long value) {
306
        prepareBuffer(index,8);
307
        return bb.putLong(index- (int) minAbs, value);
308
    }
309

    
310
    public synchronized ByteBuffer putShort(int index, short value) {
311
        prepareBuffer(index,2);
312
        return bb.putShort(index- (int) minAbs, value);
313
    }
314

    
315
    public synchronized ByteBuffer putLong(long value) {
316
        prepareBuffer(posAbs,8);
317
        return bb.putLong(value);
318
    }
319

    
320
    public synchronized ByteBuffer putShort(short value) {
321
        prepareBuffer(posAbs,2);
322
        return bb.putShort(value);
323
    }
324

    
325
    public CharBuffer asCharBuffer() {
326
        return bb.asCharBuffer();
327
    }
328

    
329
    public DoubleBuffer asDoubleBuffer() {
330
        return bb.asDoubleBuffer();
331
    }
332

    
333
    public FloatBuffer asFloatBuffer() {
334
        return bb.asFloatBuffer();
335
    }
336

    
337
    public IntBuffer asIntBuffer() {
338
        return bb.asIntBuffer();
339
    }
340

    
341
    public LongBuffer asLongBuffer() {
342
        return bb.asLongBuffer();
343
    }
344

    
345
    public ShortBuffer asShortBuffer() {
346
        return bb.asShortBuffer();
347
    }
348

    
349
    public boolean isReadOnly() {
350
        return bb.isReadOnly();
351
    }
352

    
353
    public synchronized final ByteOrder order()
354
    {
355
        return bb.order();
356
    }
357

    
358
    public synchronized final ByteBuffer order(ByteOrder bo)
359
    {
360
        return bb.order(bo);
361
    }
362
    public synchronized final long position()
363
    {
364
        return posAbs;
365
    }
366

    
367
    public synchronized final Buffer position(long newPosition)
368
    {
369
        prepareBuffer(newPosition,0);
370
        int relPos = (int) (newPosition - minAbs);
371
        if (relPos < 0)
372
            System.out.println("Position=" + newPosition);
373
        return bb.position(relPos);
374
    }
375

    
376
}