Hi All,
I'm trying to read in a binary file into java. The file format is composed of records. The records are composed of a record header and varying amounts of record fields. The record fields are stored in the binary file's own specified data types in order to provide platform independence. Some of the data types have direct java equivalents (e.g. The R4 file data type in the binary file is a 4-byte floating point number, i.e. a float), others don't have a direct java equivalent and need some conversion work when reading from the binary (e.g. U4 is a 4-byte unsigned integer).
i created a top level class to represent the record structure of the binary file composed of record classes which have the name (keys) and datatype (values) of record fields stored in a LinkedHashMap. I have a class for parsing the file, which loops through each of the record classes. For each of the records the program loops through the LinkedHashMap and according to which data type reads the binary file for the appropriate number of bits and stores the field name and actual value in another LinkedHashMap.
I done this by using a enum class to specify the each of the datatypes, to keep it typesafe, and then use a switch statement to implement the bit of code necessary to read that datatype from the file and store it.I've included some code below to illustrate:
-I'm just wondering is that an efficient way of doing reading a binary file as these files can be quite large (up to 500Mb)?
-Also, would I be better off creating an abstract readData method for the enum class and override the method for each datatype rather than using a switch statement when I want to read data from the binary ( I think it looks messy)?
I would appreciate any input!
Regards and Thanks!
P.S sorry for the essay!
// The enum class
public enum DataType {
// public enum DataType {
C1 ("char"),
B1 ("unsignedInt8"),
U1 ("unsignedInt8"),
U2 ("unsignedInt16"),
U4 ("unsignedInt32"),
U8 ("unsignedInt64"),
I1 ("byte"),
I2 ("short"),
I4 ("long"),
I8 ("signedInt64"),
R4 ("float"),
R8 ("double"),
private final String dataTypeSpecifier;
DataType(String dataType)
{
this.dataTypeSpecifier = dataType;
}
public String returnDataType()
{
return dataTypeSpecifier;
}
}
// The record class
public class RecordType {
private int recLen = 0; // Number of bytes of data following the record header
private int recTyp = 0; // An integer identifying a group of related records
private int recSub = 0; // An integer identifying a specific record type within each recTyp group
private LinkedHashMap<String,DataType> FieldMap; // Stores the list of field names for this class
private LinkedHashMap<String,Object> FieldData;
// Contsructors, Accessors, etc.
}
// The switch statement from the parsing class
switch (recordDataType){
case C1: char c1 = (char)input.readByte(); //CREATE char
thisRecordFieldData.put(recordName, c1);
recordBytesRead ++;
break;
case U1: int u1 = input.readUnsignedByte(); //create unsigned int 1 byte
thisRecordFieldData.put(recordName, u1);
recordBytesRead ++;
break;
case U2: int u2 = input.readUnsignedShort(); //create unsigned int 2 byte
thisRecordFieldData.put(recordName, u2);
recordBytesRead ++;
break;
//etc.
Edited by: LeWalrus on Feb 18, 2010 4:51 AM