Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.library / org.gvsig.utils / src / main / java / org / gvsig / utils / bigfile / BigByteBuffer2.java @ 40561

History | View | Annotate | Download (9.71 KB)

1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright (C) 2007-2013 gvSIG Association.
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 3
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23
 */
24
package org.gvsig.utils.bigfile;
25

    
26
import java.io.IOException;
27
import java.nio.Buffer;
28
import java.nio.ByteBuffer;
29
import java.nio.ByteOrder;
30
import java.nio.CharBuffer;
31
import java.nio.DoubleBuffer;
32
import java.nio.FloatBuffer;
33
import java.nio.IntBuffer;
34
import java.nio.LongBuffer;
35
import java.nio.ShortBuffer;
36
import java.nio.channels.FileChannel;
37

    
38
/**
39
 * @author Fjp
40
 *
41
 * Clase para trabajar con ficheros grandes. Mapea solo un trozo
42
 * de fichero en memoria, y cuando intentas acceder fuera de esa
43
 * zona, se ocupa de leer autom?ticamente el trozo que le falta.
44
 */
45
public class BigByteBuffer2 {
46

    
47
        private static long DEFAULT_SIZE = 60*1024; // 60 Kbytes
48

    
49
    ByteBuffer bb;
50
    // byte[] buff = new byte[1024 * 1024];;
51
    FileChannel fc;
52
    long minAbs, maxAbs, posAbs;
53
    int minRel,  maxRel, posRel;
54
    long sizeChunk, amountMem;
55
    long fileSize;
56
    FileChannel.MapMode mode;
57

    
58
    /**
59
     * Revisa la posici?n absoluta, y si hace falta, carga el buffer
60
     * con la parte de fichero que toca.
61
     * @throws IOException
62
     */
63
    private synchronized void prepareBuffer(long posActual, int numBytesToRead)
64
    {
65
        long desiredPos = posActual + numBytesToRead;
66
        if ((desiredPos > maxAbs) || (posActual < minAbs))
67
        {
68
            // Quiero leer fuera:
69
            sizeChunk = Math.min(fileSize-posActual, amountMem);
70
            try {
71
                mapFrom(posActual);
72
                // System.out.println("BigByteBuffer: min=" + minAbs
73
                //     + " maxAbs=" + maxAbs + " posAbs = " + posAbs);
74

    
75
            } catch (IOException e) {
76
                e.printStackTrace();
77

    
78
            }
79

    
80
        }
81
        // Dejamos posAbs apuntando a donde va a quedar
82
        // "a priori", antes de leer de verdad, que se hace
83
        // al salir de esta funci?n.
84
        posAbs = desiredPos;
85

    
86
    }
87

    
88
    /**
89
     * @param posActual
90
     * @throws IOException
91
     */
92
    private synchronized ByteBuffer mapFrom(long newPos) throws IOException {
93
        ByteOrder lastOrder = bb.order();
94
        // bb = fc.map(mode, newPos, sizeChunk);
95
        fc.position(newPos);
96
        // bb = ByteBuffer.wrap(buff);
97
        // bb = ByteBuffer.allocate((int)sizeChunk);
98
        bb.position(0);
99
        int numRead = fc.read(bb);
100
        bb.position(0);
101
        // System.out.println("Mapeo desde " + newPos + " con sizeChunk= " + sizeChunk + " numRead = " + numRead);
102
        minAbs = newPos;
103
        maxAbs = sizeChunk + newPos;
104
        bb.order(lastOrder);
105
        return bb;
106
    }
107

    
108
    public BigByteBuffer2(FileChannel fc, FileChannel.MapMode mode, long amountMem) throws IOException
109
    {
110
        this.amountMem = amountMem;
111
        // this.buff = new byte[(int) amountMem];
112
        this.fc = fc;
113
        this.fileSize = fc.size();
114
        this.mode = mode;
115
        sizeChunk = Math.min(fc.size(), amountMem);
116
        // bb = fc.map(mode, 0L, sizeChunk);
117
        // bb = ByteBuffer.wrap(buff);
118
        bb = ByteBuffer.allocateDirect((int)sizeChunk);
119
        int numRead = fc.read(bb);
120
        bb.position(0);
121
        minAbs = 0;
122
        maxAbs = sizeChunk;
123
    }
124
    public BigByteBuffer2(FileChannel fc, FileChannel.MapMode mode) throws IOException
125
    {
126
        this.amountMem = DEFAULT_SIZE;
127
        this.fc = fc;
128
        this.fileSize = fc.size();
129
        this.mode = mode;
130
        sizeChunk = Math.min(fc.size(), amountMem);
131
        // bb = fc.map(mode, 0L, sizeChunk);
132
        bb = ByteBuffer.allocateDirect((int)sizeChunk);
133
        int numRead = fc.read(bb);
134
        bb.position(0);
135
        minAbs = 0;
136
        maxAbs = sizeChunk;
137
    }
138

    
139

    
140
    public synchronized byte get() {
141
        prepareBuffer(posAbs,1);
142
        return bb.get();
143
    }
144
    public synchronized ByteBuffer get(byte[] dst)
145
    {
146
        prepareBuffer(posAbs, dst.length);
147
        return bb.get(dst);
148
    }
149

    
150
    public synchronized char getChar() {
151
        prepareBuffer(posAbs,2);
152
        return bb.getChar();
153
    }
154

    
155
    public synchronized double getDouble() {
156
        prepareBuffer(posAbs,8);
157
        return bb.getDouble();
158
    }
159

    
160
    public synchronized float getFloat() {
161
        prepareBuffer(posAbs,4);
162
        return bb.getFloat();
163
    }
164

    
165
    public synchronized int getInt() {
166
        prepareBuffer(posAbs,4);
167
        return bb.getInt();
168
    }
169

    
170
    public synchronized long getLong() {
171
        prepareBuffer(posAbs,8);
172
        return bb.getLong();
173
    }
174

    
175
    public synchronized short getShort() {
176
        prepareBuffer(posAbs,2);
177
        return bb.getShort();
178
    }
179

    
180
    public boolean isDirect() {
181
        return bb.isDirect();
182
    }
183

    
184
    public synchronized byte get(int index) {
185
        prepareBuffer(index,1);
186
        return bb.get(index - (int) minAbs);
187
    }
188

    
189
    public synchronized char getChar(int index) {
190
        prepareBuffer(index,2);
191
        return bb.getChar(index - (int) minAbs);
192
    }
193

    
194
    public synchronized double getDouble(int index) {
195
        prepareBuffer(index,8);
196
        return bb.getDouble(index - (int) minAbs);
197
    }
198

    
199
    public synchronized float getFloat(int index) {
200
        prepareBuffer(index,4);
201
        return bb.getFloat(index - (int) minAbs);
202
    }
203

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

    
209
    public synchronized long getLong(int index) {
210
        prepareBuffer(index,8);
211
        return bb.getLong(index - (int) minAbs);
212
    }
213

    
214
    public synchronized short getShort(int index) {
215
        prepareBuffer(index,2);
216
        return bb.getShort(index - (int) minAbs);
217
    }
218

    
219
    public ByteBuffer asReadOnlyBuffer() {
220
        return bb.asReadOnlyBuffer();
221
    }
222

    
223
    public ByteBuffer compact() {
224
        return bb.compact();
225
    }
226

    
227
    public ByteBuffer duplicate() {
228
        return bb.duplicate();
229
    }
230

    
231
    public synchronized ByteBuffer slice() {
232
        return bb.slice();
233
    }
234

    
235
    public synchronized ByteBuffer put(byte b) {
236
        prepareBuffer(posAbs,1);
237
        return bb.put(b);
238
    }
239

    
240
    public synchronized ByteBuffer putChar(char value) {
241
        prepareBuffer(posAbs,2);
242
        return bb.putChar(value);
243
    }
244

    
245
    public synchronized ByteBuffer putDouble(double value) {
246
        prepareBuffer(posAbs,8);
247
        return bb.putDouble(value);
248
    }
249

    
250
    public synchronized ByteBuffer putFloat(float value) {
251
        prepareBuffer(posAbs,4);
252
        return bb.putFloat(value);
253
    }
254

    
255
    public synchronized ByteBuffer putInt(int value) {
256
        prepareBuffer(posAbs,4);
257
        return bb.putInt(value);
258
    }
259

    
260
    public synchronized ByteBuffer put(int index, byte b) {
261
        prepareBuffer(index,1);
262
        return bb.put(index- (int) minAbs, b);
263
    }
264

    
265
    public synchronized ByteBuffer putChar(int index, char value) {
266
        prepareBuffer(index,2);
267
        return bb.putChar(index- (int) minAbs, value);
268
    }
269

    
270
    public synchronized ByteBuffer putDouble(int index, double value) {
271
        prepareBuffer(index,8);
272
        return bb.putDouble(index- (int) minAbs, value);
273
    }
274

    
275
    public synchronized ByteBuffer putFloat(int index, float value) {
276
        prepareBuffer(index,4);
277
        return bb.putFloat(index- (int) minAbs, value);
278
    }
279

    
280
    public synchronized ByteBuffer putInt(int index, int value) {
281
        prepareBuffer(index,4);
282
        return bb.putInt(index- (int) minAbs, value);
283
    }
284

    
285
    public synchronized ByteBuffer putLong(int index, long value) {
286
        prepareBuffer(index,8);
287
        return bb.putLong(index- (int) minAbs, value);
288
    }
289

    
290
    public synchronized ByteBuffer putShort(int index, short value) {
291
        prepareBuffer(index,2);
292
        return bb.putShort(index- (int) minAbs, value);
293
    }
294

    
295
    public synchronized ByteBuffer putLong(long value) {
296
        prepareBuffer(posAbs,8);
297
        return bb.putLong(value);
298
    }
299

    
300
    public synchronized ByteBuffer putShort(short value) {
301
        prepareBuffer(posAbs,2);
302
        return bb.putShort(value);
303
    }
304

    
305
    public CharBuffer asCharBuffer() {
306
        return bb.asCharBuffer();
307
    }
308

    
309
    public DoubleBuffer asDoubleBuffer() {
310
        return bb.asDoubleBuffer();
311
    }
312

    
313
    public FloatBuffer asFloatBuffer() {
314
        return bb.asFloatBuffer();
315
    }
316

    
317
    public IntBuffer asIntBuffer() {
318
        return bb.asIntBuffer();
319
    }
320

    
321
    public LongBuffer asLongBuffer() {
322
        return bb.asLongBuffer();
323
    }
324

    
325
    public ShortBuffer asShortBuffer() {
326
        return bb.asShortBuffer();
327
    }
328

    
329
    public boolean isReadOnly() {
330
        return bb.isReadOnly();
331
    }
332

    
333
    public synchronized final ByteOrder order()
334
    {
335
        return bb.order();
336
    }
337

    
338
    public synchronized final ByteBuffer order(ByteOrder bo)
339
    {
340
        return bb.order(bo);
341
    }
342
    public synchronized final long position()
343
    {
344
        return posAbs;
345
    }
346

    
347
    public synchronized final Buffer position(long newPosition)
348
    {
349
        prepareBuffer(newPosition,0);
350
        int relPos = (int) (newPosition - minAbs);
351
        if (relPos < 0)
352
            System.out.println("Position=" + newPosition);
353
        return bb.position(relPos);
354
    }
355

    
356
}