Statistics
| Revision:

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

History | View | Annotate | Download (10.3 KB)

1
/*
2
 * Created on 16-feb-2004
3
 *
4
 * To change the template for this generated file go to
5
 * Window>Preferences>Java>Code Generation>Code and Comments
6
 */
7
package com.iver.cit.gvsig.fmap.drivers.shp;
8

    
9
/**
10
 */
11
import java.io.File;
12
import java.io.FileInputStream;
13
import java.io.InputStream;
14
import java.util.Calendar;
15
import java.util.zip.GZIPInputStream;
16

    
17
/**
18
 * Class to read and write data to a dbase III format file. Creation date:
19
 * (5/15/2001 5:15:13 PM)
20
 */
21
public class DbaseFile {
22
    // verbose output flag
23
    private static boolean ourVerbose = false;
24

    
25
    // Header information for the DBase File
26
    private DbaseFileHeader myHeader;
27

    
28
    // Record Information.
29
    // private Vector myRecordVect = new Vector();
30
    private LERandomAccessFile m_fichDbf;
31

    
32
    // The file name to read or write.
33
    private String myFileName;
34

    
35
    // Convenient place to store the field names.
36
    private String[] myFieldNames;
37

    
38
    // notify about warnings.
39
    private boolean myWarning = true;
40

    
41
    /**
42
     * DbaseFile constructor comment.
43
     */
44
    public DbaseFile() {
45
        super();
46
    }
47

    
48
    /**
49
     * DbaseFile constructor comment.
50
     *
51
     * @param inFileName DOCUMENT ME!
52
     */
53
    public DbaseFile(String inFileName) {
54
        super();
55
        setFileName(inFileName);
56
    }
57

    
58
    /**
59
     * Returns the array of field names.
60
     *
61
     * @return DOCUMENT ME!
62
     */
63
    public String[] getFieldNames() {
64
        return myFieldNames;
65
    }
66

    
67
    /**
68
     * Retrieves the file name to read or write.
69
     *
70
     * @return DOCUMENT ME!
71
     */
72
    public String getFileName() {
73
        return myFileName;
74
    }
75

    
76
    // Retrieve number of records in the DbaseFile
77
    public int getNumRecords() {
78
        return myHeader.getNumRecords();
79
    }
80

    
81
    /**
82
     * DOCUMENT ME!
83
     *
84
     * @return DOCUMENT ME!
85
     */
86
    public int getNumFields() {
87
        return myHeader.getNumFields();
88
    }
89

    
90
    // Retrieve the record at the given index
91
    public Object[] getRecord(long inIndex) {
92
        long nRecordOffset = (myHeader.getRecordLength() * inIndex) +
93
            myHeader.getHeaderLength();
94

    
95
        // retrieve the record length
96
        int tempNumFields = myHeader.getNumFields();
97

    
98
        // storage for the actual values
99
        Object[] tempRow = new Object[tempNumFields];
100

    
101
        try {
102
            m_fichDbf.seek(nRecordOffset);
103

    
104
            // read the deleted flag
105
            char tempDeleted = (char) m_fichDbf.readByte();
106

    
107
            // read the record length
108
            int tempRecordLength = 1; // for the deleted character just read.
109

    
110
            // read the Fields
111
            for (int j = 0; j < tempNumFields; j++) {
112
                // find the length of the field.
113
                int tempFieldLength = myHeader.getFieldLength(j);
114
                tempRecordLength = tempRecordLength + tempFieldLength;
115

    
116
                // find the field type
117
                char tempFieldType = myHeader.getFieldType(j);
118

    
119
                //System.out.print("Reading Name="+myHeader.getFieldName(j)+" Type="+tempFieldType +" Length="+tempFieldLength);
120
                // read the data.
121
                Object tempObject = null;
122

    
123
                switch (tempFieldType) {
124
                case 'L': // logical data type, one character (T,t,F,f,Y,y,N,n)
125

    
126
                    char tempChar = (char) m_fichDbf.readByte();
127

    
128
                    if ((tempChar == 'T') || (tempChar == 't') ||
129
                            (tempChar == 'Y') || (tempChar == 'y')) {
130
                        tempObject = new Boolean(true);
131
                    } else {
132
                        tempObject = new Boolean(false);
133
                    }
134

    
135
                    break;
136

    
137
                case 'C': // character record.
138

    
139
                    byte[] sbuffer = new byte[tempFieldLength];
140
                    m_fichDbf.readFully(sbuffer);
141
                    tempObject = new String(sbuffer, "ISO-8859-1").trim();
142

    
143
                    break;
144

    
145
                case 'D': // date data type.
146

    
147
                    byte[] dbuffer = new byte[8];
148
                    m_fichDbf.readFully(dbuffer);
149

    
150
                    String tempString = new String(dbuffer, 0, 4);
151

    
152
                    try {
153
                        int tempYear = Integer.parseInt(tempString);
154
                        tempString = new String(dbuffer, 4, 2);
155

    
156
                        int tempMonth = Integer.parseInt(tempString) - 1;
157
                        tempString = new String(dbuffer, 6, 2);
158

    
159
                        int tempDay = Integer.parseInt(tempString);
160
                        Calendar c = Calendar.getInstance();
161
                        c.set(Calendar.YEAR, tempYear);
162
                        c.set(Calendar.MONTH, tempMonth);
163
                        c.set(Calendar.DAY_OF_MONTH, tempDay);
164
                        tempObject = c.getTime();
165
                    } catch (NumberFormatException e) {
166
                    }
167

    
168
                    break;
169

    
170
                case 'M': // memo field.
171

    
172
                    byte[] mbuffer = new byte[10];
173
                    m_fichDbf.readFully(mbuffer);
174

    
175
                    break;
176

    
177
                case 'N': // number
178
                case 'F': // floating point number
179

    
180
                    byte[] fbuffer = new byte[tempFieldLength];
181
                    m_fichDbf.readFully(fbuffer);
182

    
183
                    try {
184
                        tempString = new String(fbuffer);
185
                        tempObject = Double.valueOf(tempString.trim());
186
                    } catch (NumberFormatException e) {
187
                    }
188

    
189
                    break;
190

    
191
                default:
192

    
193
                    byte[] defbuffer = new byte[tempFieldLength];
194
                    m_fichDbf.readFully(defbuffer);
195
                    System.out.println("Do not know how to parse Field type " +
196
                        tempFieldType);
197
                }
198

    
199
                tempRow[j] = tempObject;
200

    
201
                //                                System.out.println(" Data="+tempObject);
202
            }
203

    
204
            // ensure that the full record has been read.
205
            if (tempRecordLength < myHeader.getRecordLength()) {
206
                byte[] tempbuff = new byte[myHeader.getRecordLength() -
207
                    tempRecordLength];
208
                m_fichDbf.readFully(tempbuff);
209

    
210
                /* if (tempTelling){
211
                        System.out.println("DBF File has "+(myHeader.getRecordLength()-tempRecordLength)+" extra bytes per record");
212
                        tempTelling = false;
213
                } */
214
            }
215
        } catch (Exception e) {
216
            e.printStackTrace();
217
        }
218

    
219
        return tempRow;
220
    }
221

    
222
    /**
223
     * Retrieve the name of the given column.
224
     *
225
     * @param inIndex DOCUMENT ME!
226
     *
227
     * @return DOCUMENT ME!
228
     */
229
    public String getFieldName(int inIndex) {
230
        return myHeader.getFieldName(inIndex);
231
    }
232

    
233
    /**
234
     * Retrieve the type of the given column.
235
     *
236
     * @param inIndex DOCUMENT ME!
237
     *
238
     * @return DOCUMENT ME!
239
     */
240
    public char getFieldType(int inIndex) {
241
        return myHeader.getFieldType(inIndex);
242
    }
243

    
244
    /**
245
     * Retrieve the length of the given column.
246
     *
247
     * @param inIndex DOCUMENT ME!
248
     *
249
     * @return DOCUMENT ME!
250
     */
251
    public int getFieldLength(int inIndex) {
252
        return myHeader.getFieldLength(inIndex);
253
    }
254

    
255
        /**
256
         * Retrieve the value of the given column as string.
257
         *
258
         * @param idField DOCUMENT ME!
259
         * @param idRecord DOCUMENT ME!
260
         *
261
         * @return DOCUMENT ME!
262
         */
263
        public Object getFieldValueAsObject(int idField, long idRecord) {
264
                Object[] tmpReg = getRecord(idRecord);
265

    
266
                return tmpReg[idField];
267
        }
268

    
269
    /**
270
     * DOCUMENT ME!
271
     *
272
     * @param idField DOCUMENT ME!
273
     * @param idRecord DOCUMENT ME!
274
     *
275
     * @return DOCUMENT ME!
276
     */
277
    public double getFieldValueAsDouble(int idField, int idRecord) {
278
        Object[] tmpReg = getRecord(idRecord);
279

    
280
        return (double) Double.parseDouble(tmpReg[idField].toString());
281
    }
282

    
283
    /**
284
     * Retrieve the location of the decimal point.
285
     *
286
     * @param inIndex DOCUMENT ME!
287
     *
288
     * @return DOCUMENT ME!
289
     */
290
    public int getFieldDecimalLength(int inIndex) {
291
        return myHeader.getFieldDecimalCount(inIndex);
292
    }
293

    
294
    /**
295
     * read the DBF file into memory.
296
     *
297
     * @throws Exception DOCUMENT ME!
298
     */
299
    public void Open() throws Exception {
300
        // create an input stream from the file
301
        if (myFileName == null) {
302
            throw new Exception("No file name specified");
303
        }
304

    
305
        InputStream fin = null;
306

    
307
        // check to see if it is a compressed file
308
        if (myFileName.toUpperCase().endsWith(".GZ")) {
309
            FileInputStream fileIn = new FileInputStream(myFileName);
310
            fin = (InputStream) new GZIPInputStream(fileIn);
311
        } else {
312
            fin = (InputStream) new FileInputStream(myFileName);
313
        }
314

    
315
        m_fichDbf = new LERandomAccessFile(myFileName, "r");
316

    
317
        // create the header to contain the header information.
318
        myHeader = new DbaseFileHeader();
319
        myHeader.readHeader(m_fichDbf);
320
        myFieldNames = new String[myHeader.getNumFields()];
321

    
322
        for (int i = 0; i < myHeader.getNumFields(); i++) {
323
            myFieldNames[i] = myHeader.getFieldName(i).trim();
324
        }
325
    }
326

    
327
    /**
328
     * Removes all data from the dataset
329
     */
330
    protected void Close() {
331
        try {
332
            m_fichDbf.close();
333
        } catch (Exception e) {
334
        }
335
    }
336

    
337
    /**
338
     * Set the file name to read or write.
339
     *
340
     * @param inFileName DOCUMENT ME!
341
     */
342
    public void setFileName(String inFileName) {
343
        if (inFileName == null) {
344
            return;
345
        }
346

    
347
        if (inFileName.length() == 0) {
348
            return;
349
        }
350

    
351
        // check if the file exists
352
        File tempFile = new File(inFileName);
353

    
354
        if (!tempFile.exists()) {
355
            if (!inFileName.toUpperCase().endsWith(".DBF")) {
356
                myFileName = inFileName + ".dbf";
357
            }
358
        } else {
359
            myFileName = inFileName;
360
        }
361
    }
362

    
363
    /**
364
     * Print warnings to system.out.
365
     *
366
     * @param inWarning DOCUMENT ME!
367
     */
368
    public void setWarnings(boolean inWarning) {
369
        myWarning = inWarning;
370

    
371
        if (myHeader == null) {
372
            myHeader = new DbaseFileHeader();
373
        }
374

    
375
        myHeader.setWarnings(inWarning);
376
    }
377

    
378
    // Set the verbose mode for output from this class
379
    public static void setVerbose(boolean inVerbose) {
380
        ourVerbose = inVerbose;
381
    }
382
}