package uk.ac.leeds.ccg.dbffile; import java.io.*; import java.util.*; import java.lang.*; import java.net.*; import cmp.LEDataStream.*; /** * * This class represents a DBF (or DBase) file.

* Construct it with a URL or File (including the .dbf) * this causes the header and field definitions to be read.

* Later queries return rows or columns of the database.

* If a URL is specified then the whole file is read into memory
* if a file is specified then a randomAccess system is used.
*


* @author Ian Turton Centre for * Computaional Geography, University of Leeds, LS2 9JT, 1998. *
* mod to getStringCol by James Macgill. */ public class Dbf implements DbfConsts{ static final boolean DEBUG=false; static final String DBC="Dbf->"; int dbf_id; int last_update_d,last_update_m,last_update_y; int last_rec; int data_offset; int rec_size; StringBuffer records[]; int position=0; boolean hasmemo; boolean isFile = false; RandomAccessFile rFile; LEDataInputStream dFile; int filesize,numfields; public DbfFieldDef fielddef[]; /** * Constructor, opens the file and reads the header infomation. * @param file The file to be opened, includes path and .dbf * @exception java.io.IOException If the file can't be opened. * @exception DbfFileException If there is an error reading header. */ public Dbf(URL url) throws java.io.IOException,DbfFileException{ if(DEBUG)System.out.println("---->uk.ac.leeds.ccg.dbffile.Dbf constructed. Will identify itself as "+DBC); URLConnection uc = url.openConnection(); InputStream in = uc.getInputStream(); LEDataInputStream sfile = new LEDataInputStream(in); init(sfile); } public Dbf(InputStream in) throws java.io.IOException,DbfFileException{ if(DEBUG)System.out.println("---->uk.ac.leeds.ccg.dbffile.Dbf constructed. Will identify itself as "+DBC); LEDataInputStream sfile = new LEDataInputStream(in); init(sfile); } public Dbf(String name) throws java.io.IOException,DbfFileException{ if(DEBUG)System.out.println("---->uk.ac.leeds.ccg.dbffile.Dbf constructed. Will identify itself as "+DBC); URL url = new URL(name); URLConnection uc = url.openConnection(); InputStream in = uc.getInputStream(); LEDataInputStream sfile = new LEDataInputStream(in); init(sfile); } public Dbf(File file) throws java.io.IOException,DbfFileException{ if(DEBUG)System.out.println("---->uk.ac.leeds.ccg.dbffile.Dbf constructed. Will identify itself as "+DBC); InputStream in = new FileInputStream(file); LEDataInputStream sfile = new LEDataInputStream(in); rFile=new RandomAccessFile(file,"r"); isFile=true; init(sfile); } /** * Returns the date of the last update of the file as a string. */ public String getLastUpdate(){ String date=last_update_d+"/"+(last_update_m+1)+"/"+(1900+last_update_y); return date; } /** * Returns the number of records in the database file. */ public int getLastRec(){ return last_rec; } /** * Returns the size of the records in the database file. */ public int getRecSize(){ return rec_size; } /** * Returns the number of fields in the records in the database file. */ public int getNumFields(){ return numfields; } /** * looks up the field number for the given named column * @param name A String for the name to look up * @return int The col number for the field, -1 if field could not be found */ public int getFieldNumber(String name){ for(int i=0;i=numfields) throw new IllegalArgumentException(DBC+"column number specified is invalid. It's higher than the amount of columns available "+numfields); return fielddef[col].fieldname; } public char getFieldType(int col){ if(col>=numfields) throw new IllegalArgumentException(DBC+"column number specified is invalid. It's higher than the amount of columns available"+numfields); return fielddef[col].fieldtype; } /** * initailizer, allows the use of multiple constructers in later * versions. */ private void init(LEDataInputStream sfile)throws IOException,DbfFileException { DbfFileHeader head = new DbfFileHeader(sfile); int widthsofar; dFile=sfile; fielddef = new DbfFieldDef[numfields]; widthsofar=1; for(int index=0;indexrowth row of the file * @param row - the row to fetch * @exception java.io.IOException on read error. */ public StringBuffer GetDbfRec(int row)throws java.io.IOException{ StringBuffer record;// = new StringBuffer(rec_size); if(!isFile){ return record = new StringBuffer(records[row].toString()); } else{ record = new StringBuffer(rec_size+numfields); rFile.seek(data_offset+(rec_size*row)); //Modifed to use Hisaji ONO's approach for reading multi byte character sets byte[] strbuf = new byte[rec_size]; // <---- byte array buffer fo storing string's byte data for(int i=0;irowth row of the file and parses it into an vector * of objects. * @param row - the row to fetch * @exception java.io.IOException on read error. */ public Vector ParseDbfRecord(int row)throws java.io.IOException{ return ParseRecord(GetDbfRec(row)); } /** * Parses the record stored in the StringBuffer rec into a vector of * objects * @param StringBuffer rec - the record to be parsed. */ public Vector ParseRecord(StringBuffer rec){ Vector record=new Vector(numfields); String t; Integer I=new Integer(0); Float F=new Float(0.0); t = rec.toString(); for(int i=0;i=numfields) throw new DbfFileException(DBC+"No Such Column in file: "+col); if(fielddef[col].fieldtype!='N') throw new DbfFileException(DBC+"Column "+col+" is not Integer "+ fielddef[col].fieldtype); if(start<0) throw new DbfFileException(DBC+"Start must be >= 0"); if(end>last_rec) throw new DbfFileException(DBC+"End must be <= "+last_rec); // move to start of data try{ for(i=start;irecord "+i+" byte "+k+" file pos " );} catch(java.io.IOException e){ System.err.println(e); System.err.println("Dbf->record "+i+" byte "+k+" file pos " );} return column; } /** * Fetches a column of Floats from the database file. * @param int col - the column to fetch * @exception java.io.IOException - on read error * @exception DbfFileException - column is not an Integer. */ public Float[] getFloatCol(int col) throws DbfFileException, java.io.IOException{ return getFloatCol(col,0,last_rec); } /** * Fetches a part column of Floats from the database file. * @param int col - the column to fetch * @param int start - the row to start fetching from * @param int end - the row to stop fetching at. * @exception java.io.IOException - on read error * @exception DbfFileException - column is not an Integer. */ public Float[] getFloatCol(int col,int start,int end) throws DbfFileException, java.io.IOException{ Float column[]=new Float[end-start]; String record,st; StringBuffer sb = new StringBuffer(rec_size); int k=0,i=0; if(col>=numfields) throw new DbfFileException("Dbf->No Such Column in file: "+col); if(fielddef[col].fieldtype!='F'&&fielddef[col].fieldtype!='N') throw new DbfFileException("Dbf->Column "+col+" is not Float " +fielddef[col].fieldtype); if(start<0) throw new DbfFileException("Dbf->Start must be >= 0"); if(end>last_rec) throw new DbfFileException("Dbf->End must be <= "+last_rec); // move to start of data try{ for(i=start;i"+e); System.err.println("Dbf->record "+i+" byte "+k+" file pos ");} catch(java.io.IOException e){ System.err.println("Dbf->"+e); System.err.println("Dbf->record "+i+" byte "+k+" file pos ");} return column; } /** * Fetches a column of Strings from the database file. * @param int col - the column to fetch * @exception java.io.IOException - on read error * @exception DbfFileException - column is not an Integer. */ public String[] getStringCol(int col) throws DbfFileException, java.io.IOException{ return getStringCol(col,0,last_rec); } /** * Fetches a part column of Strings from the database file. * @param int col - the column to fetch * @param int start - the row to start fetching from * @param int end - the row to stop fetching at. * @exception java.io.IOException - on read error * @exception DbfFileException - column is not an Integer. */ public String[] getStringCol(int col,int start,int end) throws DbfFileException, java.io.IOException{ String column[]=new String[end-start]; String record = new String(); StringBuffer sb = new StringBuffer(numfields); int k=0,i=0; if(col>=numfields) throw new DbfFileException("Dbf->No Such Column in file: "+col); //if(fielddef[col].fieldtype!='C') //throw new DbfFileException("Column "+col+" is not a String"); if(start<0) throw new DbfFileException("Dbf->Start must be >= 0"); if(end>last_rec) throw new DbfFileException("Dbf->End must be <= "+last_rec); // move to start of data try{ for(i=start;i"+e); System.err.println("Dbf->record "+i+" byte "+k+" file pos ");} catch(java.io.IOException e){ System.err.println("Dbf->"+e); System.err.println("Dbf->record "+i+" byte "+k+" file pos ");} return column; } }