Statistics
| Revision:

root / trunk / libraries / libFMap / src / com / iver / cit / gvsig / fmap / drivers / shp / DbaseFileNIO.java @ 1100

History | View | Annotate | Download (10.5 KB)

1
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
2
 *
3
 * Copyright (C) 2004 IVER T.I. and Generalitat Valenciana.
4
 *
5
 * This program is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU General Public License
7
 * as published by the Free Software Foundation; either version 2
8
 * of the License, or (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
18
 *
19
 * For more information, contact:
20
 *
21
 *  Generalitat Valenciana
22
 *   Conselleria d'Infraestructures i Transport
23
 *   Av. Blasco Ib??ez, 50
24
 *   46010 VALENCIA
25
 *   SPAIN
26
 *
27
 *      +34 963862235
28
 *   gvsig@gva.es
29
 *      www.gvsig.gva.es
30
 *
31
 *    or
32
 *
33
 *   IVER T.I. S.A
34
 *   Salamanca 50
35
 *   46005 Valencia
36
 *   Spain
37
 *
38
 *   +34 963163400
39
 *   dac@iver.es
40
 */
41
package com.iver.cit.gvsig.fmap.drivers.shp;
42

    
43
import java.io.File;
44
import java.io.FileInputStream;
45
import java.io.IOException;
46

    
47
import java.nio.ByteBuffer;
48
import java.nio.channels.FileChannel;
49

    
50

    
51
/**
52
 * Class to read and write data to a dbase III format file. Creation date:
53
 * (5/15/2001 5:15:13 PM)
54
 */
55
public class DbaseFileNIO {
56
        // Header information for the DBase File
57
        private DbaseFileHeaderNIO myHeader;
58
        private FileInputStream fin;
59
        private FileChannel channel;
60
        private ByteBuffer buffer;
61

    
62
        /**
63
         * Retrieve number of records in the DbaseFile
64
         *
65
         * @return N?mero de registros.
66
         */
67
        public int getRecordCount() {
68
                return myHeader.getNumRecords();
69
        }
70

    
71
        /**
72
         * Devuelve el n?mero de fields.
73
         *
74
         * @return N?mero de fields.
75
         */
76
        public int getFieldCount() {
77
                return myHeader.getNumFields();
78
        }
79

    
80
        /**
81
         * Devuelve el valor de un boolean a partir de su n?mero de fila y de
82
         * field.
83
         *
84
         * @param rowIndex N?mero de fila.
85
         * @param fieldId N?mero columna.
86
         *
87
         * @return boolean.
88
         */
89
        public boolean getBooleanFieldValue(int rowIndex, int fieldId) {
90
                int recordOffset = (myHeader.getRecordLength() * rowIndex) +
91
                        myHeader.getHeaderLength() + 1;
92

    
93
                //Se calcula el offset del campo
94
                int fieldOffset = 0;
95

    
96
                for (int i = 0; i < (fieldId - 1); i++) {
97
                        fieldOffset += myHeader.getFieldLength(i);
98
                }
99

    
100
                buffer.position(recordOffset + fieldOffset);
101

    
102
                char bool = (char) buffer.get();
103

    
104
                return ((bool == 't') || (bool == 'T') || (bool == 'Y') ||
105
                (bool == 'y'));
106
        }
107

    
108
        /**
109
         * Devuelve el String a partir del n?mero de fila y columna.
110
         *
111
         * @param rowIndex N?mero de fila.
112
         * @param fieldId N?mero de columna.
113
         *
114
         * @return String.
115
         */
116
        public String getStringFieldValue(int rowIndex, int fieldId) {
117
                int recordOffset = (myHeader.getRecordLength() * rowIndex) +
118
                        myHeader.getHeaderLength() + 1;
119

    
120
                //Se calcula el offset del campo
121
                int fieldOffset = 0;
122

    
123
                for (int i = 0; i < fieldId; i++) {
124
                        fieldOffset += myHeader.getFieldLength(i);
125
                }
126

    
127
                buffer.position(recordOffset + fieldOffset);
128

    
129
                byte[] data = new byte[myHeader.getFieldLength(fieldId)];
130
                buffer.get(data);
131

    
132
                return new String(data);
133
        }
134

    
135
        /**
136
         * Devuelve el Number a partir de una fila y columna.
137
         *
138
         * @param rowIndex N?mero fila.
139
         * @param fieldId N?mero columna.
140
         *
141
         * @return Number.
142
         */
143
        public Number getNumberFieldValue(int rowIndex, int fieldId) {
144
                //System.out.println("rowIndex = "+rowIndex+ " , "+"fieldId = "+fieldId);
145
                int recordOffset = (myHeader.getRecordLength() * rowIndex) +
146
                        myHeader.getHeaderLength() + 1;
147

    
148
                //Se calcula el offset del campo
149
                int fieldOffset = 0;
150

    
151
                for (int i = 0; i < fieldId; i++) {
152
                        fieldOffset += myHeader.getFieldLength(i);
153
                }
154

    
155
                buffer.position(recordOffset + fieldOffset);
156

    
157
                byte[] data = new byte[myHeader.getFieldLength(fieldId)];
158
                buffer.get(data);
159

    
160
                String s = new String(data);
161
                s = s.trim();
162

    
163
                if (getFieldType(fieldId) == 'N') {
164
                        Object tempObject = Double.valueOf(s);
165

    
166
                        return new Double(tempObject.toString());
167
                } else {
168
                        Object tempObject = Integer.valueOf(s);
169

    
170
                        return new Integer(tempObject.toString());
171
                }
172

    
173
                //return 0;
174
        }
175

    
176
        // Retrieve the record at the given index
177

    
178
        /*    public Object[] getRecord(long inIndex) throws IOException {
179
           long nRecordOffset = (myHeader.getRecordLength() * inIndex) +
180
               myHeader.getHeaderLength();
181
           // retrieve the record length
182
           int tempNumFields = myHeader.getNumFields();
183
           // storage for the actual values
184
           Object[] tempRow = new Object[tempNumFields];
185
               buffer.position((int) nRecordOffset);
186
               // read the deleted flag
187
               char tempDeleted = (char) buffer.get();
188
               // read the record length
189
               int tempRecordLength = 1; // for the deleted character just read.
190
               // read the Fields
191
               for (int j = 0; j < tempNumFields; j++) {
192
                   // find the length of the field.
193
                   int tempFieldLength = myHeader.getFieldLength(j);
194
                   tempRecordLength = tempRecordLength + tempFieldLength;
195
                   // find the field type
196
                   char tempFieldType = myHeader.getFieldType(j);
197
                   //System.out.print("Reading Name="+myHeader.getFieldName(j)+" Type="+tempFieldType +" Length="+tempFieldLength);
198
                   // read the data.
199
                   Object tempObject = null;
200
                   switch (tempFieldType) {
201
                   case 'L': // logical data type, one character (T,t,F,f,Y,y,N,n)
202
                       char tempChar = (char) buffer.get();
203
                       if ((tempChar == 'T') || (tempChar == 't') ||
204
                               (tempChar == 'Y') || (tempChar == 'y')) {
205
                           tempObject = new Boolean(true);
206
                       } else {
207
                           tempObject = new Boolean(false);
208
                       }
209
                       break;
210
                   case 'C': // character record.
211
                       byte[] sbuffer = new byte[tempFieldLength];
212
                                           buffer.get(sbuffer);
213
                       tempObject = new String(sbuffer, "ISO-8859-1").trim();
214
                       break;
215
                   case 'D': // date data type.
216
                       byte[] dbuffer = new byte[8];
217
                                           buffer.get(dbuffer);
218
                       String tempString = new String(dbuffer, 0, 4);
219
                       try {
220
                           int tempYear = Integer.parseInt(tempString);
221
                           tempString = new String(dbuffer, 4, 2);
222
                           int tempMonth = Integer.parseInt(tempString) - 1;
223
                           tempString = new String(dbuffer, 6, 2);
224
                           int tempDay = Integer.parseInt(tempString);
225
                           Calendar c = Calendar.getInstance();
226
                           c.set(Calendar.YEAR, tempYear);
227
                           c.set(Calendar.MONTH, tempMonth);
228
                           c.set(Calendar.DAY_OF_MONTH, tempDay);
229
                           tempObject = c.getTime();
230
                       } catch (NumberFormatException e) {
231
                       }
232
                       break;
233
                   case 'M': // memo field.
234
                       byte[] mbuffer = new byte[10];
235
                                           buffer.get(mbuffer);
236
                       break;
237
                   case 'N': // number
238
                   case 'F': // floating point number
239
                       byte[] fbuffer = new byte[tempFieldLength];
240
                                           buffer.get(fbuffer);
241
                       try {
242
                           tempString = new String(fbuffer);
243
                           tempObject = Double.valueOf(tempString.trim());
244
                       } catch (NumberFormatException e) {
245
                       }
246
                       break;
247
                   default:
248
                       byte[] defbuffer = new byte[tempFieldLength];
249
                                           buffer.get(defbuffer);
250
                       System.out.println("Do not know how to parse Field type " +
251
                           tempFieldType);
252
                   }
253
                   tempRow[j] = tempObject;
254
                   //                                System.out.println(" Data="+tempObject);
255
               }
256
               // ensure that the full record has been read.
257
               if (tempRecordLength < myHeader.getRecordLength()) {
258
                   byte[] tempbuff = new byte[myHeader.getRecordLength() -
259
                       tempRecordLength];
260
                   buffer.get(tempbuff);
261
                   /* if (tempTelling){
262
                           System.out.println("DBF File has "+(myHeader.getRecordLength()-tempRecordLength)+" extra bytes per record");
263
                           tempTelling = false;
264
                   } */
265
        /*           }
266
           return tempRow;
267
           }
268
         */
269

    
270
        /**
271
         * Retrieve the name of the given column.
272
         *
273
         * @param inIndex ?ndice.
274
         *
275
         * @return nombre del campo.
276
         */
277
        public String getFieldName(int inIndex) {
278
                return myHeader.getFieldName(inIndex).trim();
279
        }
280

    
281
        /**
282
         * Retrieve the type of the given column.
283
         *
284
         * @param inIndex ?ndice.
285
         *
286
         * @return tipo de campo.
287
         */
288
        public char getFieldType(int inIndex) {
289
                return myHeader.getFieldType(inIndex);
290
        }
291

    
292
        /**
293
         * Retrieve the length of the given column.
294
         *
295
         * @param inIndex indice.
296
         *
297
         * @return longitud del field.
298
         */
299
        public int getFieldLength(int inIndex) {
300
                return myHeader.getFieldLength(inIndex);
301
        }
302

    
303
        /*
304
         * Retrieve the value of the given column as string.
305
         *
306
         * @param idField DOCUMENT ME!
307
         * @param idRecord DOCUMENT ME!
308
         *
309
         * @return DOCUMENT ME!
310
         *
311
                 public Object getFieldValue(int idField, long idRecord) throws IOException {
312
                     Object[] tmpReg = getRecord(idRecord);
313
                     return tmpReg[idField];
314
                 }
315
         */
316
        /*
317
         * DOCUMENT ME!
318
         *
319
         * @param idField DOCUMENT ME!
320
         * @param idRecord DOCUMENT ME!
321
         *
322
         * @return DOCUMENT ME!
323
         *
324
                 public double getFieldValueAsDouble(int idField, int idRecord) throws IOException {
325
                     Object[] tmpReg = getRecord(idRecord);
326
                     return (double) Double.parseDouble(tmpReg[idField].toString());
327
                 }
328
         */
329

    
330
        /**
331
         * Retrieve the location of the decimal point.
332
         *
333
         * @param inIndex ?ndice.
334
         *
335
         * @return localizaci?n.
336
         */
337
        public int getFieldDecimalLength(int inIndex) {
338
                return myHeader.getFieldDecimalCount(inIndex);
339
        }
340

    
341
        /**
342
         * read the DBF file into memory.
343
         *
344
         * @param file Fichero.
345
         *
346
         * @throws IOException
347
         */
348
        public void open(File file) throws IOException {
349
                fin = new FileInputStream(file);
350
                channel = fin.getChannel();
351

    
352
                buffer = channel.map(FileChannel.MapMode.READ_ONLY, 0, channel.size());
353

    
354
                // create the header to contain the header information.
355
                myHeader = new DbaseFileHeaderNIO();
356
                myHeader.readHeader(buffer);
357
        }
358

    
359
        /**
360
         * Removes all data from the dataset
361
         *
362
         * @throws IOException .
363
         */
364
        public void close() throws IOException {
365
                fin.close();
366
                channel.close();
367
        }
368
}