com.linuxense.javadbf.DBFReader Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of javadbf Show documentation
Show all versions of javadbf Show documentation
JavaDBF is a Java library for reading and writing XBase files.
/*
(C) Copyright 2015-2017 Alberto Fernández
(C) Copyright 2004,2014 Jan Schlößin
(C) Copyright 2003-2004 Anil Kumar K
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3.0 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library. If not, see .
*/
package com.linuxense.javadbf;
import java.io.Closeable;
import java.io.DataInputStream;
import java.io.EOFException;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.BitSet;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TimeZone;
/**
* DBFReader class can creates objects to represent DBF data.
*
* This Class is used to read data from a DBF file. Meta data and records can be
* queried against this document.
*
*
* DBFReader cannot write to a DBF file. For creating DBF files use DBFWriter.
*
*
* Fetching records is possible only in the forward direction and cannot be
* re-wound. In such situations, a suggested approach is to reconstruct the
* object.
*
*
* The nextRecord() method returns an array of Objects and the types of these
* Object are as follows:
*
*
*
*
* xBase Type
* Java Type
*
*
*
*
* C
* String
*
*
* N
* java.math.BigDecimal
*
*
* F
* java.math.BigDecimal
*
*
* L
* Boolean
*
*
* D
* java.util.Date
*
*
* Y
* java.math.BigDecimal
*
*
* I
* Integer
*
*
* T
* java.util.Date
*
*
* @
* java.util.Date
*
*
*
* Integer
*
*
* V
* String
*
*
* O
* Double
*
*
* M
* java.lang.String or byte[]
*
*
* B
* byte[] or java.lang.Double
*
*
* G
* byte[]
*
*
* P
* byte[]
*
*
* Q
* byte[]
*
*
*
*/
public class DBFReader extends DBFBase implements Closeable {
private static final long MILLISECS_PER_DAY = 24*60*60*1000;
private static final long TIME_MILLIS_1_1_4713_BC = -210866803200000L;
protected InputStream inputStream;
protected DataInputStream dataInputStream;
private DBFHeader header;
private boolean trimRightSpaces = true;
private DBFMemoFile memoFile = null;
private boolean closed = false;
private Map mapFieldNames = new HashMap();
private boolean showDeletedRows = false;
/**
* Intializes a DBFReader object.
*
* Tries to detect charset from file, if failed uses default charset ISO-8859-1
* When this constructor returns the object will have completed reading the
* header (meta date) and header information can be queried there on. And it
* will be ready to return the first row.
*
* @param in the InputStream where the data is read from.
*/
public DBFReader(InputStream in) {
this(in,null,false);
}
/**
* Intializes a DBFReader object.
*
* Tries to detect charset from file, if failed uses default charset ISO-8859-1
* When this constructor returns the object will have completed reading the
* header (meta date) and header information can be queried there on. And it
* will be ready to return the first row.
*
* @param in the InputStream where the data is read from.
* @param showDeletedRows can be used to identify records that have been deleted.
*/
// TODO Change to boolean in 2.0
public DBFReader(InputStream in, Boolean showDeletedRows) {
this(in,null, showDeletedRows);
}
/**
* Initializes a DBFReader object.
*
* When this constructor returns the object will have completed reading the
* header (meta date) and header information can be queried there on. And it
* will be ready to return the first row.
*
* @param in the InputStream where the data is read from.
* @param charset charset used to decode field names and field contents. If null, then is autedetected from dbf file
*/
public DBFReader(InputStream in,Charset charset) {
this(in, charset, false);
}
/**
* Initializes a DBFReader object.
*
* When this constructor returns the object will have completed reading the
* header (meta date) and header information can be queried there on. And it
* will be ready to return the first row.
*
* @param in the InputStream where the data is read from.
* @param charset charset used to decode field names and field contents. If null, then is autedetected from dbf file
* @param showDeletedRows can be used to identify records that have been deleted.
*/
public DBFReader(InputStream in, Charset charset, boolean showDeletedRows) {
try {
this.showDeletedRows = showDeletedRows;
this.inputStream = in;
this.dataInputStream = new DataInputStream(this.inputStream);
this.header = new DBFHeader();
this.header.read(this.dataInputStream, charset, showDeletedRows);
setCharset(this.header.getUsedCharset());
/* it might be required to leap to the start of records at times */
int fieldSize = this.header.getFieldDescriptorSize();
int tableSize = this.header.getTableHeaderSize();
int t_dataStartIndex = this.header.headerLength - (tableSize + (fieldSize * this.header.fieldArray.length)) - 1;
skip(t_dataStartIndex);
this.mapFieldNames = createMapFieldNames(this.header.userFieldArray);
} catch (IOException e) {
DBFUtils.close(dataInputStream);
DBFUtils.close(in);
throw new DBFException(e.getMessage(), e);
}
}
private Map createMapFieldNames(DBFField[] fieldArray) {
Map fieldNames = new HashMap();
for (int i = 0; i < fieldArray.length; i++) {
String name = fieldArray[i].getName();
fieldNames.put(name.toLowerCase(), i);
}
return Collections.unmodifiableMap(fieldNames);
}
/**
Returns the number of records in the DBF. This number includes deleted (hidden) records
@return number of records in the DBF file.
*/
public int getRecordCount() {
return this.header.numberOfRecords;
}
/**
* Returns the last time the file was modified
* @return the las time the file was modified
*/
public Date getLastModificationDate() {
if (this.header != null) {
return this.header.getLastModificationDate();
}
return null;
}
/**
* Returns the asked Field. In case of an invalid index, it returns a
* ArrayIndexOutofboundsException.
*
* @param index Index of the field. Index of the first field is zero.
* @return Field definition for selected field
*/
public DBFField getField(int index) {
return new DBFField(this.header.userFieldArray[index]);
}
/**
* Returns the number of field in the DBF.
* @return number of fields in the DBF file
*/
public int getFieldCount() {
return this.header.userFieldArray.length;
}
/**
* Reads the returns the next row in the DBF stream.
*
* @return The next row as an Object array. Types of the elements these
* arrays follow the convention mentioned in the class description.
*/
public Object[] nextRecord() {
if (this.closed) {
throw new IllegalArgumentException("this DBFReader is closed");
}
List