Reading data from binary file correctly in Java - java

I have problem with reading understood data, when I used Parsing (char) the numbers became strange char in ASCII, here is the code :
static void doTestByteFiles() throws IOException {
File file = new File("sample1.data");
FileOutputStream outStream = new FileOutputStream(file); //Warning!!!!
byte[] outByteArray = {10,20,30,40,50,60,70,80,(byte)'J',(byte)'a',(byte)'v',(byte)'a'};
outStream.write(outByteArray);
outStream.close();
FileInputStream inStream = new FileInputStream(file);
int fileSize = (int) file.length();
byte[] inByteArray = new byte[fileSize];
inStream.read(inByteArray);
for (int i = 0; i < fileSize; i++) {
System.out.println((char) inByteArray[i]);
}
inStream.close();
}
the result:
(
2
<
F
P
J
a
v
a
result I expect :
10
20
30
40
50
60
70
80
J
a
v
a
I tried to use (byte) instead (char), same problem but the Java word became numbers in ASCII , Any help please ?

The numbers in the byte[] array are interpreted as byte values. You have to write Intergers and convert them to byte inside the array.

Related

How to properly validate PNG header in java?

I'm trying to write a function which will check if PNG file is not corrupted. Here I found a function, also provided below, which stores file bytes into its own byte array. I know that the first eight bytes of a PNG file always contain the same decimal values 137 80 78 71 13 10 26 10 (hex: 89 50 4e 47 0d 0a 1a 0a).
When I print the context of the byte array which starts with -1-40-1-3201674707370011007207200-1-370-124022222232235333565555686666681088888810101010101 ... and then convert it to decimal values I don't see the magic number in the beginning. Please, what have I misunderstood? I would like to read the image and compare its header to either decimal or hex values.
public static void main(String[] args)
{
File file = new File("src/resources/dog.png");
readContentIntoByteArray(file);
}
private static byte[] readContentIntoByteArray(File file)
{
FileInputStream fileInputStream = null;
byte[] bFile = new byte[(int) file.length()];
try
{
//convert file into array of bytes
fileInputStream = new FileInputStream(file);
fileInputStream.read(bFile);
fileInputStream.close();
for (int i = 0; i < bFile.length; i++)
{
System.out.print((char) bFile[i]);
}
}
catch (Exception e)
{
e.printStackTrace();
}
return bFile;
}
You are printing the actual bytes as characters to the terminal, not the representation of those bytes in decimal or hex, as #Andreas says.
You can check the header with:
byte[] data = readContentIntoByteArray(file);
byte[] expected = new byte[] {-119, 80, 78, 71, 13, 10, 26, 10};
for (int i = 0; i < expected.length; i++) {
if (expected[i] != data[i]) {
System.out.println("mismatch at " + i);
}
}

Convert hexadecimal file into unsigned int 32 Big-Endian in Java

It might be a question already asked, but I have not found a satisfactory answer yet out there. In particular because this conversion has always been done in c or C++.
Btw, how do you convert an hexadecimal file (200MB) into its UINT32 Big-endian representation in Java?
This an example of what I am trying to achieve:
54 00 00 00 -> 84
55 F1 2E 04 -> 70185301
A2 3F 32 01 -> 20070306
and so on
EDIT
File fileInputString = new File(inputFileField.getText());
FileInputStream fin = new FileInputStream(fileInputString);
FileOutputStream out = new FileOutputStream(fileDirectoryFolder.getText() +"/"+ fileInputString.getName());
byte[] fileContent = new byte[(int)fileInputString.length()];
fin.read(fileContent);
System.out.println("File Lenght" + fileContent.length);
for(int i = 0; i < fileContent.length; i++){
Byte b = fileContent[i]; // Boxing conversion converts `byte` to `Byte`
int value = b.intValue();
out.write(value);
}
close();
System.out.println("Done");
EDIT 2
File fileInputString = new File(inputFileField.getText());
FileInputStream fin = new FileInputStream(fileInputString);
FileOutputStream out = new FileOutputStream(fileDirectoryFolder.getText() +"/"+ fileInputString.getName());
ByteArrayOutputStream bos = new ByteArrayOutputStream();
byte[] fileContent = new byte[(int)fileInputString.length()];
System.out.println("File Lenght" + fileContent.length);
int bytesRead;
while (( bytesRead = fin.read(fileContent)) != -1) {
ByteBuffer.wrap(fileContent).order(ByteOrder.LITTLE_ENDIAN).getLong();
bos.write(fileContent, 0, bytesRead);
}
out.write(bos.toByteArray());
System.out.println("Done");
EDIT 3
DataOutputStream out = new DataOutputStream(new FileOutputStream(output));
DataInputStream in = new DataInputStream(new FileInputStream(input))) {
int count = 0;
while (count < input.length() - 4) {
in.readFully(buffer, 4, 4);
String s=Long.toString(ByteBuffer.wrap(buffer).order(ByteOrder.LITTLE_ENDIAN).getLong());
out.writeBytes( s + " ");
count += 4;
}
Thanks
The following code should hopefully suffice. It uses long values to ensure we can fully represent the range of positive values that four bytes can represent.
Note: this code assumes the hex input is four bytes. You may want to add some more checks and measures in production code.
private static long toLong(String hex) {
hex = hex.replace(" ", "") + "00000000";
byte[] data = DatatypeConverter.parseHexBinary(hex);
return ByteBuffer.wrap(data).order(ByteOrder.LITTLE_ENDIAN).getLong();
}
public static void main(String[] args) throws Exception {
System.out.println(toLong("54 00 00 00"));
System.out.println(toLong("55 F1 2E 04"));
System.out.println(toLong("A2 3F 32 01"));
System.out.println(toLong("FF FF FF FF"));
}
Output:
84
70185301
20070306
4294967295
Based on your recent edits, I propose some code such as the following. Note that it assumes your input is a multiple of four bytes in length. Any left-over bytes are ignored:
File input = new File("whatever");
byte[] buffer = new byte[8];
List<Long> result = new ArrayList<>();
try (DataInputStream in = new DataInputStream(new FileInputStream(input))) {
int count = 0;
// Note: any trailing bytes are ignored
while (count < input.length() - 4) {
in.readFully(buffer, 4, 4);
result.add(ByteBuffer.wrap(buffer)
.order(ByteOrder.LITTLE_ENDIAN).getLong());
count += 4;
}
}
You need to switch the byte order within the 4 bytes that form an int. The conversion is symetric, so when the input is little endian, output becomes big endian and vice versa.
Big Endian: 12 34 56 78
Little Endian: 78 56 34 12
So if you were doing that while processing an InputStream, read four bytes, and write them to output in reverse order.

Not able to buffer special characters

while (!bStop) {
byte[] buffer = new byte[256];
if (inputStream.available() > 0) {
inputStream.read(buffer);
int i = 0;
for (i = 0; i < buffer.length && buffer[i] != 0; i++) {
}
final String strInput = new String(buffer, 0, i);
System.out.println(strInput);`
}
The inputstream data is coming in encrypted form in bytes. When i print the data i get funny characters. How can i directly convert the inputstream to hexadecimal in a form of -> 01 2A 03 AA.
Please Help.
try like this
byte[] array = ByteStreams.toByteArray(inputStream);

Encoding String to "modified UTF-8" for the DataInput

I would like to encode String value to the modified UTF-8 format bytes. Something like
byte[] bytes = MagicEncoder.encode(str, "modified UTF-8");
DataInput input = new DataInputStream(new ByteArrayInputStream(bytes));
Each read*() method of the DataInput has to be able to properly read the underlaying bytes.
Use DataOutputStream
ByteArrayOutputStream byteOutputStream = new ByteArrayOutputStream();
DataOutputStream dataOutputStream = new DataOutputStream(byteOutputStream);
dataOutputStream.writeUTF("some string to write");
dataOutputStream.close();
result is available in byteOutputStream.toByteArray()
As info:
The modified UTF-8 encoding simply replaces the nul character U+0000, normally encoded as byte 0, as the byte sequence C0 80, the normal multi-byte encoding, used for codes > 0x7F.
(Hence normal UTF-8 decoding suffices.)
byte[] originalBytes;
int nulCount = 0;
for (int i = 0; i < originalBytes.length; ++i) {
if (originalBytes[i] == 0) {
++nulCount;
}
}
byte[] convertedBytes = new byte[originalCount + nulCount];
for (int i = 0, j = 0; i < originalBytes.length; ++i, ++j) {
convertedBytes[j] = originalBytes[i];
if (originalBytes[i] == 0) {
convertedBytes[j] = 0xC0;
++j;
convertedBytes[j] = 0x80;
}
}
Better to use System.arrayCopy, and check whether nulCount == 0.

How I can divide a file to blocks in java?

I try make code by java able to read 100 kb from file then divide the file into blocks each block has 256 bit or 32 byte also I want conver each block to binary format or integer format the following is it
I need any suggest
public static void main(String[] args) {
ReadFileExample newclass = new ReadFileExample();
System.out.println("-----------Wellcome in ECC ENCRYPTION NEW--------");
File clearmsg = new File("F:/java_projects/clearmsg.txt");
File ciphermsg = new File("F:/java_projects/ciphermsg.txt");
byte[] block = new byte[32];
try {
FileInputStream fis = new FileInputStream(clearmsg);
FileOutputStream fos = new FileOutputStream(ciphermsg);
CipherOutputStream cos = new CipherOutputStream(fos);
System.out.println("Total file size to read (in bytes) : "
+ fis.available());
int i;
while ((i = fis.read(block)) != -1) {
System.out.println(block);
fos.write(block, 0, i);
}
fos.close();

Categories