/** * This method saves all the records in the mapTable argument using the dos stream. * * @param dos Output stream writing to the .dbf file. * @param mapTable The dbf table being saved. * @throws IOException Thrown when the stream fails. */ private void saveRecords(DataOutputStream dos, DBFTable mapTable) throws IOException { // WRITE ALL ROW DATA for (int i = 0; i < mapTable.getNumberOfRecords(); i++) { // HERE'S THE RECORD WE ARE SAVING DBFRecord recordToSave = mapTable.getRecord(i); // THERE IS A MYSTERY BYTE BEFORE EACH RECORD dos.writeByte(recordToSave.getMystery()); // LOAD DATA FOR EACH FIELD Iterator<DBFField> fieldsIt = mapTable.fieldsIterator(); int fieldsCounter = 0; while (fieldsIt.hasNext()) { // WHAT TYPE OF FIELD IS IT (character data, numbers, etc.)? DBFField field = fieldsIt.next(); // TEXT? if (field.getType() == DBFFieldType.C) { int j = 0; Object data = recordToSave.getData(fieldsCounter); String text; if (data == null) text = ""; else text = data.toString(); while (j < text.length()) { dos.writeByte((byte) text.charAt(j)); j++; } while (j < field.getLength()) { dos.writeByte((byte) ' '); j++; } } // IT MUST BE AN 'N' TYPE, THOSE ARE THE ONLY TWO WE'RE USING else { Object data = recordToSave.getData(fieldsCounter); String numText; if (data == null) numText = ""; else numText = data.toString(); int x = 0; while (x < numText.length()) { dos.writeByte((byte) numText.charAt(x)); x++; } while (x < field.getLength()) { dos.writeByte((byte) ' '); x++; } } fieldsCounter++; } } }
/** * This helper method reads and loads all the row data (records) from the .dbf into the mapTable * argument. Note that the dis argument must be ready to read at the start of the records section, * which is right after the fields section. * * @param dis Input stream reading from the .dbf file. * @param mapTable The dbf table being loaded. * @throws IOException Thrown when the stream fails. */ private void loadRecords(DataInputStream dis, DBFTable mapTable) throws IOException { // READ ALL ROW DATA for (int i = 0; i < mapTable.getNumberOfRecords(); i++) { // HERE'S THE RECORD WE ARE LOADING DBFRecord recordToAdd = new DBFRecord(mapTable.getNumFields()); // THERE IS A MYSTERY BYTE BEFORE EACH RECORD byte mystery = dis.readByte(); recordToAdd.setMystery(mystery); // LOAD DATA FOR EACH FIELD Iterator<DBFField> fieldsIt = mapTable.fieldsIterator(); int fieldsCounter = 0; while (fieldsIt.hasNext()) { // WHAT TYPE OF FIELD IS IT (character data, numbers, etc.)? DBFField field = fieldsIt.next(); // TEXT? if (field.getType() == DBFFieldType.C) { String text = ""; for (int counter = 0; counter < field.getLength(); counter++) { char c = (char) dis.readByte(); text += c; } text = text.trim(); recordToAdd.setData(text, fieldsCounter); } // IT MUST BE AN 'N' TYPE SINCE THOSE ARE THE ONLY TWO WE'RE USING else { String text = ""; for (int counter = 0; counter < field.getLength(); counter++) { char c = (char) dis.readByte(); text += c; } text = text.trim(); if (text.contains(".")) { double num = 0.0; num = Double.parseDouble(text); recordToAdd.setData(num, fieldsCounter); } else { long num = 0; if (text.length() > 0) num = Long.parseLong(text); recordToAdd.setData(num, fieldsCounter); } } fieldsCounter++; } // Comparable key = (Comparable)recordToAdd.getData(mapTable.getKeyIndex()); mapTable.addRecord(recordToAdd); } }
/** * This helper method saves just the .dbf file header portion of the mapTable argument using the * dos stream. * * @param dos The stream writing to the .dbf file. * @param mapTable The dbf table being saved. * @throws IOException Thrown when the stream fails. */ private void saveHeader(DataOutputStream dos, DBFTable mapTable) throws IOException { // DBF file type (0) dos.writeByte(mapTable.getFileType()); // LAST UPDATE (1-3) byte year = (byte) (mapTable.getLastModifiedDate().get(Calendar.YEAR) - 1900); byte month = (byte) (mapTable.getLastModifiedDate().get(Calendar.MONTH) + 1); byte day = (byte) (mapTable.getLastModifiedDate().get(Calendar.DATE)); dos.writeByte(year); dos.writeByte(month); dos.writeByte(day); // NUMBER OF RECORDS IN FILE (4-7) int numberOfRecordsInFile = Integer.reverseBytes(mapTable.getNumberOfRecords()); dos.writeInt(numberOfRecordsInFile); // POSITION OF FIRST DATA RECORDED (8-9) short positionOfFirstDataRecorded = Short.reverseBytes(mapTable.getPositionOfFirstDataRecorded()); dos.writeShort(positionOfFirstDataRecorded); // LENGTH OF ONE DATA RECORD, INCLUDING DELETE FLAG (10-11) short dataRecordLength = Short.reverseBytes(mapTable.getDataRecordLength()); dos.writeShort(dataRecordLength); // ZEROES (12-13) short zeroes = Short.reverseBytes(mapTable.getZeroes()); dos.writeShort(zeroes); // DBASE IV Transaction Flag (14) dos.writeByte(mapTable.getDbaseTransactionFlag()); // DBASE IV Encryption Flag (15) dos.writeByte(mapTable.getDbaseEncryptionFlag()); // Multiuser Processing 12 Bytes (16-27) int[] mup = mapTable.getMup(); dos.writeInt(Integer.reverseBytes(mup[0])); dos.writeInt(Integer.reverseBytes(mup[1])); dos.writeInt(Integer.reverseBytes(mup[2])); // TABLE FLAGS (28) dos.writeByte(mapTable.getFlags()); // CODE PAGE MARK/LANGUAGE DRIVER ID (29) dos.writeByte(mapTable.getCodePageMark()); // RESERVED, CONTAINS 0x00 (30-31) dos.writeShort(Short.reverseBytes(mapTable.getReserved())); }