I'm trying to read a .dat using Java with no other Classes. This is the file's structure: Header Serial: Word; //2 bytes Filename: String[255]; //1 byte Date: Word; //2 bytes FieldNumbers: Word; //2 bytes NumbersOfRecords: Word; //2 bytes
Info about Fields
FieldCode: Word; //2 bytes
FieldName: ShortString; //1 byte
Info in Field
FieldCode: Word; //2 bytes
FieldText: String[255]; //1 byte
DateTime = double
What I must know is how to use BufferedReader to get each Byte, read it as an int, then turn same int to a string and show it on screen. Can I create different Methods for reading each type of data? Can I make it read 2 bytes at the same time?
UPDATE:
package binarios5;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
public class Main5
{
public static void main(String[] args) throws FileNotFoundException, IOException
{
try
{
Path path = Paths.get("C:\\\\Dev-Pas\\\\EXAMEN2.dat");
System.out.println("File open");
byte[] bytes = Files.readAllBytes(path);
ByteBuffer buffer = ByteBuffer.wrap(bytes);
buffer.order(ByteOrder.BIG_ENDIAN);
short serial = buffer.getShort();
System.out.println("----[CONTENIDO DEL ARCHIVO]--------------------");
System.out.println("Nro. de Serie: " + serial);
int largoCadena = buffer.get();//Bytes 1 int Longitud de la cadena
//System.out.println("largoCadena: " + largoCadena);//33
byte[] bytesChar = new byte[largoCadena];//CString
buffer.get(bytesChar);
String nombre = new String(bytesChar, StandardCharsets.ISO_8859_1);
System.out.println("Nombre: " + nombre);
short date = buffer.getShort();//FALTA DECODIFICAR FECHA
System.out.println("Fecha sin procesar. "+date);//FALTA DECODIFICAR FECHA
short cantCampos = buffer.getShort(); //cantidad de campos que tienen los registros
System.out.println("Cantidad de Campos Customizados: "+cantCampos);//debe decir 4
int[] codCampo = new int[cantCampos];
String[] nombreCampo = new String[10];
for (int i = 0; i < cantCampos; i++) //leer RegType segun la cantidad de campos
{
codCampo[i] = buffer.getShort();//Bytes 2 codigo del campo
int largoCadena2 = buffer.get();//Bytes 1 int Longitud de la cadena
byte[] bytesChar2 = new byte[largoCadena2];
buffer.get(bytesChar2);
nombreCampo[i] = new String(bytesChar2, StandardCharsets.ISO_8859_1);
}
for (int i = 0; i < cantCampos; i++)//mostrar codigos y campos
{
System.out.println("Campo [codigo: " + codCampo[i] + ", descripcion: " + nombreCampo[i] + "]");
}
short cantRegistros = buffer.getShort();//cantidad de registros total
System.out.println("Cantidad de Registros: "+cantRegistros);
System.out.println("-----------------------");//OK
String[] contenidoCampo = new String[10];
for (int i = 0; i < cantRegistros; i++) //leyendo RegData 5 veces
{
short cantCamposCompletos = buffer.getShort();
for (int j = 0; j < cantCamposCompletos; j++)
{
short codCampoInterno = buffer.getShort();
int largoCadena3 = buffer.get();
byte[] bytesChar3 = new byte[largoCadena3];
buffer.get(bytesChar3);
contenidoCampo[j] = new String(bytesChar3, StandardCharsets.ISO_8859_1);
System.out.println(nombreCampo[j]+": "+contenidoCampo[j]);
}
System.out.println("-----------------------");
}
System.out.println("----[FIN CONTENIDO DEL ARCHIVO]-----------------");
}
catch (IOException e)
{
System.out.println("File I/O error!");
}
}
}
In java Reader and Writer are for Unicode text, String, 2-bytes char.
For binary data, byte[]
one needs an InputStream, OutputStream.
One can use an InputStream:
BufferedInputStream in = new BufferedInputStream(new FileInputStream(...));
In your case you want to read short and such. For that you could wrap it around a DataInputStream.
However using a ByteBuffer is easiest to begin with. It can be read from a file (FileChannel), but the simple case is:
Path path = Paths.get("C:/xxx/yyy.dat");
byte[] bytes = Files.readAllBytes(path);
ByteBuffer buffer = ByteBuffer.wrap(bytes);
//buffer.order(ByteOrder.LITTLE_ENDIAN); // So short is read as LSB,MSB
Worked out:
// Header
short serial = buffer.getShort();
byte[] fileNameB = new byte[255];
buffer.get(fileNameB);
// If 0 terminated asciz string:
int len = fileNameB.length;
for (int i = 0; i < fileNameB.length; ++i) {
if (fileNameB[i] == 0) {
len = i;
break;
}
}
String fileName = new String(fileNameB, 0, len, StandardCharsets.ISO_8859_1);
short date = buffer.getShort();
short fieldNumbers = buffer.getShort();
short numbersOfRecords = buffer.getShort();
for (int fieldI = 0; fieldI < fieldNumber; ++fieldI) {
// Info about Fields
short fieldCode = buffer.getShort();
//byte fieldName: ShortString; //1 byte
}
Info in Field FieldCode: Word; //2 bytes FieldText: String[255]; //1 byte
DateTime = double
String getPascalString(ByteBuffer buffer) {
int length = buffer.get() & 0xFF;
byte[] bytes = new byte[length];
buffer.get(bytes);
return new String(bytes, StandardCharsets.ISO_8859_1);
}
Will deliver:
d:/documentos/te...
short packedDate = buffer.getShort();
int year = packedDate & 0x7F; // + 1900?
int month = (packedDate >> 7) & 0xF:
int day = (packedDate >> 11) & 0x1F;
Readers are meant for reading streams of characters. For reading streams of raw bytes, consider using a InputStream and calling
public int read(byte[] b)
To parse the strings, pass the byte array to the string constructor specifying the encoding (don't use default encoding because it could be utf8 depending of you environment and in your case is not suitable).
https://docs.oracle.com/javase/tutorial/essential/io/index.html
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.