Statistics
| Revision:

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

History | View | Annotate | Download (9.26 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.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
    public synchronized byte get() {
137
        prepareBuffer(posAbs,1);
138
        return bb.get();
139
    }
140
    public synchronized ByteBuffer get(byte[] dst)
141
    {
142
        prepareBuffer(posAbs, dst.length);
143
        return bb.get(dst);
144
    }
145

    
146
    public synchronized char getChar() {
147
        prepareBuffer(posAbs,2);
148
        return bb.getChar();
149
    }
150

    
151
    public synchronized double getDouble() {
152
        prepareBuffer(posAbs,8);
153
        return bb.getDouble();
154
    }
155

    
156
    public synchronized float getFloat() {
157
        prepareBuffer(posAbs,4);
158
        return bb.getFloat();
159
    }
160

    
161
    public synchronized int getInt() {
162
        prepareBuffer(posAbs,4);
163
        return bb.getInt();
164
    }
165

    
166
    public synchronized long getLong() {
167
        prepareBuffer(posAbs,8);
168
        return bb.getLong();
169
    }
170

    
171
    public synchronized short getShort() {
172
        prepareBuffer(posAbs,2);
173
        return bb.getShort();
174
    }
175

    
176
    public boolean isDirect() {
177
        return bb.isDirect();
178
    }
179

    
180
    public synchronized byte get(int index) {
181
        prepareBuffer(index,1);
182
        return bb.get(index - (int) minAbs);
183
    }
184

    
185
    public synchronized char getChar(int index) {
186
        prepareBuffer(index,2);
187
        return bb.getChar(index - (int) minAbs);
188
    }
189

    
190
    public synchronized double getDouble(int index) {
191
        prepareBuffer(index,8);
192
        return bb.getDouble(index - (int) minAbs);
193
    }
194

    
195
    public synchronized float getFloat(int index) {
196
        prepareBuffer(index,4);
197
        return bb.getFloat(index - (int) minAbs);
198
    }
199

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

    
205
    public synchronized long getLong(int index) {
206
        prepareBuffer(index,8);
207
        return bb.getLong(index - (int) minAbs);
208
    }
209

    
210
    public synchronized short getShort(int index) {
211
        prepareBuffer(index,2);
212
        return bb.getShort(index - (int) minAbs);
213
    }
214

    
215
    public ByteBuffer asReadOnlyBuffer() { 
216
        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
    public synchronized ByteBuffer put(byte b) {
232
        prepareBuffer(posAbs,1);
233
        return bb.put(b);
234
    }
235

    
236
    public synchronized ByteBuffer putChar(char value) {
237
        prepareBuffer(posAbs,2);
238
        return bb.putChar(value);
239
    }
240

    
241
    public synchronized ByteBuffer putDouble(double value) {
242
        prepareBuffer(posAbs,8);
243
        return bb.putDouble(value);
244
    }
245

    
246
    public synchronized ByteBuffer putFloat(float value) {
247
        prepareBuffer(posAbs,4);
248
        return bb.putFloat(value);
249
    }
250

    
251
    public synchronized ByteBuffer putInt(int value) {
252
        prepareBuffer(posAbs,4);
253
        return bb.putInt(value);
254
    }
255

    
256
    public synchronized ByteBuffer put(int index, byte b) {
257
        prepareBuffer(index,1);
258
        return bb.put(index- (int) minAbs, b);
259
    }
260

    
261
    public synchronized ByteBuffer putChar(int index, char value) {
262
        prepareBuffer(index,2);
263
        return bb.putChar(index- (int) minAbs, value);
264
    }
265

    
266
    public synchronized ByteBuffer putDouble(int index, double value) {
267
        prepareBuffer(index,8);
268
        return bb.putDouble(index- (int) minAbs, value);
269
    }
270

    
271
    public synchronized ByteBuffer putFloat(int index, float value) {
272
        prepareBuffer(index,4);
273
        return bb.putFloat(index- (int) minAbs, value);
274
    }
275

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

    
281
    public synchronized ByteBuffer putLong(int index, long value) {
282
        prepareBuffer(index,8);
283
        return bb.putLong(index- (int) minAbs, value);
284
    }
285

    
286
    public synchronized ByteBuffer putShort(int index, short value) {
287
        prepareBuffer(index,2);
288
        return bb.putShort(index- (int) minAbs, value);
289
    }
290

    
291
    public synchronized ByteBuffer putLong(long value) {
292
        prepareBuffer(posAbs,8);
293
        return bb.putLong(value);
294
    }
295

    
296
    public synchronized ByteBuffer putShort(short value) {
297
        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
    public synchronized final Buffer position(long newPosition)
344
    {
345
        prepareBuffer(newPosition,0);
346
        int relPos = (int) (newPosition - minAbs);
347
        // System.out.println("Position=" + newPosition);
348
        return bb.position(relPos);
349
    }
350

    
351
}