Statistics
| Revision:

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

History | View | Annotate | Download (8.96 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.MappedByteBuffer;
36
import java.nio.ShortBuffer;
37
import java.nio.channels.FileChannel;
38

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

    
48
    private static long DEFAULT_SIZE = 50*1024*1024; // 50 Megas m?ximo
49
    
50
    MappedByteBuffer bb;
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 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
                ByteOrder lastOrder = bb.order();
72
                bb = fc.map(mode, posActual, sizeChunk);
73
                minAbs = posActual;
74
                maxAbs = sizeChunk + posActual;
75
                bb.order(lastOrder);
76
                // System.out.println("BigByteBuffer: min=" + minAbs 
77
                //     + " maxAbs=" + maxAbs + " posAbs = " + posAbs);
78
                
79
            } catch (IOException e) {
80
                // TODO Auto-generated catch block
81
                e.printStackTrace();
82
            }
83
                
84
        }
85
        // Dejamos posAbs apuntando a donde va a quedar
86
        // "a priori", antes de leer de verdad, que se hace
87
        // al salir de esta funci?n.
88
        posAbs = desiredPos;
89
        
90
    }
91
    
92
    public BigByteBuffer(FileChannel fc, FileChannel.MapMode mode, long amountMem) throws IOException
93
    {
94
        this.amountMem = amountMem;
95
        this.fc = fc;
96
        this.fileSize = fc.size();
97
        this.mode = mode;
98
        sizeChunk = Math.min(fc.size(), amountMem);
99
        bb = fc.map(mode, 0L, sizeChunk);
100
        minAbs = 0;
101
        maxAbs = sizeChunk;
102
    }
103
    public BigByteBuffer(FileChannel fc, FileChannel.MapMode mode) throws IOException
104
    {
105
        this.amountMem = DEFAULT_SIZE;
106
        this.fc = fc;
107
        this.fileSize = fc.size();
108
        this.mode = mode;
109
        sizeChunk = Math.min(fc.size(), amountMem);
110
        bb = fc.map(mode, 0L, sizeChunk);
111
        minAbs = 0;
112
        maxAbs = sizeChunk;
113
    }
114

    
115
    
116
    public synchronized byte get() {
117
        prepareBuffer(posAbs,1);
118
        return bb.get();
119
    }
120
    public synchronized ByteBuffer get(byte[] dst)
121
    {
122
        prepareBuffer(posAbs, dst.length);
123
        return bb.get(dst);
124
    }
125

    
126
    public synchronized char getChar() {
127
        prepareBuffer(posAbs,2);
128
        return bb.getChar();
129
    }
130

    
131
    public synchronized double getDouble() {
132
        prepareBuffer(posAbs,8);
133
        return bb.getDouble();
134
    }
135

    
136
    public synchronized float getFloat() {
137
        prepareBuffer(posAbs,4);
138
        return bb.getFloat();
139
    }
140

    
141
    public synchronized int getInt() {
142
        prepareBuffer(posAbs,4);
143
        return bb.getInt();
144
    }
145

    
146
    public synchronized long getLong() {
147
        prepareBuffer(posAbs,8);
148
        return bb.getLong();
149
    }
150

    
151
    public synchronized short getShort() {
152
        prepareBuffer(posAbs,2);
153
        return bb.getShort();
154
    }
155

    
156
    public boolean isDirect() {
157
        return bb.isDirect();
158
    }
159

    
160
    public synchronized byte get(int index) {
161
        prepareBuffer(index,1);
162
        return bb.get(index - (int) minAbs);
163
    }
164

    
165
    public synchronized char getChar(int index) {
166
        prepareBuffer(index,2);
167
        return bb.getChar(index - (int) minAbs);
168
    }
169

    
170
    public synchronized double getDouble(int index) {
171
        prepareBuffer(index,8);
172
        return bb.getDouble(index - (int) minAbs);
173
    }
174

    
175
    public synchronized float getFloat(int index) {
176
        prepareBuffer(index,4);
177
        return bb.getFloat(index - (int) minAbs);
178
    }
179

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

    
185
    public synchronized long getLong(int index) {
186
        prepareBuffer(index,8);
187
        return bb.getLong(index - (int) minAbs);
188
    }
189

    
190
    public synchronized short getShort(int index) {
191
        prepareBuffer(index,2);
192
        return bb.getShort(index - (int) minAbs);
193
    }
194

    
195
    public ByteBuffer asReadOnlyBuffer() { 
196
        return bb.asReadOnlyBuffer();
197
    }
198

    
199
    public ByteBuffer compact() {
200
        return bb.compact();
201
    }
202

    
203
    public ByteBuffer duplicate() {
204
        return bb.duplicate();
205
    }
206

    
207
    public ByteBuffer slice() {
208
        return bb.slice();
209
    }
210

    
211
    public synchronized ByteBuffer put(byte b) {
212
        prepareBuffer(posAbs,1);
213
        return bb.put(b);
214
    }
215

    
216
    public synchronized ByteBuffer putChar(char value) {
217
        prepareBuffer(posAbs,2);
218
        return bb.putChar(value);
219
    }
220

    
221
    public synchronized ByteBuffer putDouble(double value) {
222
        prepareBuffer(posAbs,8);
223
        return bb.putDouble(value);
224
    }
225

    
226
    public synchronized ByteBuffer putFloat(float value) {
227
        prepareBuffer(posAbs,4);
228
        return bb.putFloat(value);
229
    }
230

    
231
    public synchronized ByteBuffer putInt(int value) {
232
        prepareBuffer(posAbs,4);
233
        return bb.putInt(value);
234
    }
235

    
236
    public synchronized ByteBuffer put(int index, byte b) {
237
        prepareBuffer(index,1);
238
        return bb.put(index- (int) minAbs, b);
239
    }
240

    
241
    public synchronized ByteBuffer putChar(int index, char value) {
242
        prepareBuffer(index,2);
243
        return bb.putChar(index- (int) minAbs, value);
244
    }
245

    
246
    public synchronized ByteBuffer putDouble(int index, double value) {
247
        prepareBuffer(index,8);
248
        return bb.putDouble(index- (int) minAbs, value);
249
    }
250

    
251
    public synchronized ByteBuffer putFloat(int index, float value) {
252
        prepareBuffer(index,4);
253
        return bb.putFloat(index- (int) minAbs, value);
254
    }
255

    
256
    public synchronized ByteBuffer putInt(int index, int value) {
257
        prepareBuffer(index,4);
258
        return bb.putInt(index- (int) minAbs, value);
259
    }
260

    
261
    public synchronized ByteBuffer putLong(int index, long value) {
262
        prepareBuffer(index,8);
263
        return bb.putLong(index- (int) minAbs, value);
264
    }
265

    
266
    public synchronized ByteBuffer putShort(int index, short value) {
267
        prepareBuffer(index,2);
268
        return bb.putShort(index- (int) minAbs, value);
269
    }
270

    
271
    public synchronized ByteBuffer putLong(long value) {
272
        prepareBuffer(posAbs,8);
273
        return bb.putLong(value);
274
    }
275

    
276
    public synchronized ByteBuffer putShort(short value) {
277
        prepareBuffer(posAbs,2);
278
        return bb.putShort(value);
279
    }
280

    
281
    public CharBuffer asCharBuffer() {
282
        return bb.asCharBuffer();
283
    }
284

    
285
    public DoubleBuffer asDoubleBuffer() {
286
        return bb.asDoubleBuffer();
287
    }
288

    
289
    public FloatBuffer asFloatBuffer() {
290
        return bb.asFloatBuffer();
291
    }
292

    
293
    public IntBuffer asIntBuffer() {
294
        return bb.asIntBuffer();
295
    }
296

    
297
    public LongBuffer asLongBuffer() {
298
        return bb.asLongBuffer();
299
    }
300

    
301
    public ShortBuffer asShortBuffer() {
302
        return bb.asShortBuffer();
303
    }
304

    
305
    public boolean isReadOnly() {
306
        return bb.isReadOnly();
307
    }
308
    
309
    public final ByteOrder order()
310
    {
311
        return bb.order();
312
    }
313

    
314
    public final ByteBuffer order(ByteOrder bo)
315
    {
316
        return bb.order(bo);
317
    }
318
    public final long position()
319
    {
320
        return posAbs;
321
    }
322
    
323
    public synchronized final Buffer position(long newPosition)
324
    {
325
        prepareBuffer(newPosition,0);
326
        int relPos = (int) (newPosition - minAbs);
327
        // System.out.println("Position=" + newPosition);
328
        return bb.position(relPos);
329
    }
330

    
331
}