java - ERROR converting from byte[] to File (hex values) - java

Okay guys, I have a file with some HEX values as well as a program that take this values with a byte[] in order to convert some hex values and then reconvert it to a file.
The problem is that when I reconvert de byte array to a file some hex values are modified, and I don't find the problem.
If you see any possible mistake don't hesitate.
As you can see I have a test.sav file, here it is:
And this is the product of the program, the two files are different and they should be the same because any change has been made:
Here is the code:
public class Test {
public static File file;
public static String hex;
public static byte[] mext;
public static byte[] bytearray;
public static void main(String[] args) throws IOException {
file = new File("C:\\Users\\Roman\\Desktop\\test.sav");
StringBuilder sb = new StringBuilder();
FileInputStream fin = null;
try {
fin = new FileInputStream(file);
bytearray = new byte[(int)file.length()];
fin.read(bytearray);
for(byte bytev : bytearray){
sb.append(String.format("%02X", bytev));
}
System.out.println(sb);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {}
//replaceMax(); <-- I deduced that conversion is not the problem
save(); // THIS IS THE IMPORTANT PART
}
public static void save() throws IOException{
PrintWriter pw = new PrintWriter("C:\\Users\\Roman\\Desktop\\test2.sav");
pw.write("");
pw.close();
FileWriter fw = new FileWriter(new File("C:\\Users\\Roman\\Desktop\\test2.sav"));
BufferedWriter out = new BufferedWriter(fw);
out.write(new String(bytearray, "ASCII"));
out.close();
}
}

You are reading data from a binary file and then trying to write it out as a character stream. Furthermore you're forcing it to use ASCII (a 7 bit character set) as the character encoding.
Try altering the save method to use:
FileOutputStream output = new FileOutputStream("C:\\Users\\Roman\\Desktop\\test2.sav");
try {
output.write(bytearray);
} finally {
output.close();
}
This will avoid character (re)encoding issues.

Related

Generate a PDF using Streams [duplicate]

This question already has answers here:
Convert InputStream to byte array in Java
(34 answers)
Closed 4 years ago.
I am trying to convert an InputStream into a byte array to write it in a file, to generate a PDF.
I have a File type with the url of a PDF, and with that, i have the inputStream of that.
File fichero_pdf = new File("C:/Users/agp2/Desktop/PDF_TRIAXE.pdf");
InputStream stream4 = new FileInputStream(fichero_pdf);
Until here everything is perfect, the problem appears when i try to transform this InputStream to a byte[] and write it in a new File.
I have these two methods:
to convert the Stream to a byte[]:
private static byte[] getArrayFromInputStream(InputStream is) {
BufferedReader br = null;
StringBuilder sb = new StringBuilder();
String line;
try {
br = new BufferedReader(new InputStreamReader(is));
while ((line = br.readLine()) != null) {
sb.append(line+"\n");
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return sb.toString().getBytes();
}
To write the byte[] in the new file:
...
File file=new File(dto.getTitulo());
InputStream stream=dto.getContenido();
byte[] array=getStringFromInputStream(stream);
OutputStream salida=new FileOutputStream(file);
salida.write(array);
salida.close();
stream.close();
helper.addAttachment(file.getName(), file);
}
mailSender.send(message);
...
The Email is sent at perfection, but when i can't open the .pdf.
Also, i compare the code of the new pdf with the code of the first, and is a little bit different.
I need to create a valid pdf file from an inputStream.
You have 2 problems:
You are trying to read bytes as strings, but you don't have to do it. In your case you should use byte streams(FileInputStream, BufferedInputStream), not char streams(InputStreamReader, BufferedReader).
You loose data when you convert String to bytes here:
return sb.toString().getBytes();
I would like to suggest you to use java 7 try-with-resources instead of try-catch-finally.
You can read the whole file to a byte array using ByteArrayOutputStream.
Sample code does the following:
getArrayFromInputStream() - reads all file bytes to byte array
writeContent() - writes content to a new file, in my example pdf_sample2.pdf
Example:
public class ReadAllBytes {
// as example - write to resources folder
private static String DIR = "src\\main\\resources\\";
public static void main(String[] args) throws IOException {
try {
byte[] fileAsBytes = getArrayFromInputStream(new FileInputStream(new File(DIR + "pdf-sample.pdf")));
writeContent(fileAsBytes, DIR + "pdf_sample2.pdf");
} catch (Exception e){
e.printStackTrace();
}
}
private static byte[] getArrayFromInputStream(InputStream inputStream) throws IOException {
byte[] bytes;
byte[] buffer = new byte[1024];
try(BufferedInputStream is = new BufferedInputStream(inputStream)){
ByteArrayOutputStream bos = new ByteArrayOutputStream();
int length;
while ((length = is.read(buffer)) > -1 ) {
bos.write(buffer, 0, length);
}
bos.flush();
bytes = bos.toByteArray();
}
return bytes;
}
private static void writeContent(byte[] content, String fileToWriteTo) throws IOException {
File file = new File(fileToWriteTo);
try(BufferedOutputStream salida = new BufferedOutputStream(new FileOutputStream(file))){
salida.write(content);
salida.flush();
}
}
}

How to write out percentage of file copying using Binary Stream?

I want to show the percentage while copying file by using binary stream but I don't know the way, that How to do it?
Below is my code.
public static void binaryStream() throws IOException {
try {
FileInputStream inputStream = new FileInputStream(new File("Untitled.png"));
FileOutputStream outputStream = new FileOutputStream(new File("Untitled-copied.png"));
int data;
while ((data = inputStream.read()) >= 0) {
outputStream.write(data);
}
outputStream.write(data);
inputStream.close();
outputStream.close();
} catch (FileNotFoundException e) {
System.out.println("Error");
} catch (IOException e) {
System.out.println("Error");
}
}
Example of how to do it like other people mentioned in the comments.
import java.io.*;
public class BinaryStream {
public static void binaryStream(String file1, String file2) throws Exception
{
File sourceFile = new File(file1);
try(
FileInputStream inputStream = new FileInputStream(sourceFile);
FileOutputStream outputStream = new FileOutputStream(new File(file2))
) {
long lenOfFile = sourceFile.length();
long currentBytesWritten = 0;
int data;
while ((data = inputStream.read()) != -1) {
outputStream.write(data);
currentBytesWritten += 1;
System.out.printf("%2.2f%%%n",
100*((double)currentBytesWritten)/((double)lenOfFile));
}
}
}
public static void main(String args[]) throws Exception {
binaryStream("Untitled.png", "Untitled-copied.png");
}
}
Note that I've made some changes:
Removed the extra outputStream.write() call you had that was writing extra content incorrectly
Using try-with-resources idiom to close the streams you open even on exceptions
Throw the exceptions instead of catching, as you shouldn't catch them if you can't handle them
Compare to -1, as that is the documented value for end of file (end of stream)
Output is like this on my computer:
0,06%
// removed data
99,89%
99,94%
100,00%
Note also that this code will print something after each byte written, so it is highly inefficient. You might want to do that less often. On that note, you're reading and writing one byte at a time, which is also very inefficient - you might want to use read(byte[]) instead, reading in chunks. Example of that, using 256 byte array:
import java.io.*;
public class BinaryStream {
public static void binaryStream(String file1, String file2) throws Exception {
File sourceFile = new File(file1);
try(
FileInputStream inputStream = new FileInputStream(sourceFile);
FileOutputStream outputStream = new FileOutputStream(new File(file2))
) {
long lenOfFile = sourceFile.length();
long bytesWritten = 0;
int amountOfBytesRead;
byte[] bytes = new byte[256];
while ((amountOfBytesRead = inputStream.read(bytes)) != -1) {
outputStream.write(bytes, 0, amountOfBytesRead);
bytesWritten += amountOfBytesRead;
System.out.printf("%2.2f%%%n",
100*((double)bytesWritten)/((double)lenOfFile));
}
}
}
public static void main(String args[]) throws Exception {
binaryStream("Untitled.png", "Untitled-copied.png");
}
}
Output on my computer:
14,69%
29,37%
44,06%
58,75%
73,44%
88,12%
100,00%
Note that in the first example, return value of .read() is actually the byte that was read, whereas in the second example, return value of .read() is the amount of bytes read and the actual bytes go into the byte array.

Why isn't my output in byte code? When using FileOutputStream and using the .getBytes method

This is the code that I'm using, when I run it and open the output file, I see Hello world saved.
Why is it like this?
public class Fileoutputstream {
public static void main(String [] args) throws IOException {
File file = null;
FileOutputStream fileOut = null;
try {
file = new File("output");
if (!file.exists()) {
file.createNewFile();
}
fileOut = new FileOutputStream(file, true);
String textToSave = "Hello World";
byte[] textToSaveBytes = textToSave.getBytes();
fileOut.write(textToSaveBytes);
fileOut.close();
} catch (Exception e) {
}
}
}
The bytes you written into the file is actually the ASCII code string so no doubt your output file's a text file.
Most programs will treat file as 'text' if there is no non-text character in it, i.e NULL byte, control character etc..

How to write binary to a file in Java

I am trying to get input from a file, convert the characters to binary and then output the binary to another output file.
I used Integer.toBinaryString() in order to make the conversion.
Everything is working as it should but for some reason nothing is written to the output file, but when I use System.out.println() it outputs fine.
import java.io.*;
public class Binary {
FileReader fRead = null;
FileWriter fWrite = null;
byte[] bFile = null;
String fileIn;
private String binaryString(int bString) {
String binVal = Integer.toBinaryString(bString);
while (binVal.length() < 8) {
binVal = "0" + binVal;
}
return binVal;
}
public void input() throws IOException, UnsupportedEncodingException {
try {
fRead = new FileReader("in.txt");
BufferedReader reader = new BufferedReader(fRead);
fileIn = reader.readLine();
bFile = fileIn.getBytes("UTF-8");
fWrite = new FileWriter("out.txt");
BufferedWriter writer = new BufferedWriter(fWrite);
for (byte b: bFile) {
writer.write(binaryString(b));
System.out.println(binaryString(b));
}
System.out.println("Done.");
} catch (Exception e) {
e.printStackTrace();
}
}
public Binary() {
}
public static void main(String[] args) throws UnsupportedEncodingException, IOException {
Binary b = new Binary();
b.input();
}
}
I know my code is not very good, I'm relatively new to Java so I don't know many others ways to accomplish this.
Use Output stream instead of Writer as writer is not supposed to be used for writing binary content
FileOutputStream fos = new FileOutputStream(new File("output.txt"));
BufferedOutputStream bos = new BufferedOutputStream(fos);
bos.write(b); // in loop probably

A String from hashing is no longer the same after output to a file and then input

Here is the weird thing which has already taken me a whole day:
If a write a simple String like "1" to a file and read it immediately, the string fetched equals the original String.
But if the String is generated by some hash function, the String fetched is no longer the same.
The follow code prints true false, and I want to know the trick behind the scene.
Thank you very much.
public static void main(String[] args) {
try {
String s1 = "1";
File f1 = new File("f1");
write (s1, f1);
System.out.println(read(f1).equals(s1));
MessageDigest md = MessageDigest.getInstance("SHA-512");
String s2 = foo(new File("1.jpg"), md);
File f2 = new File("f2");
write (s2, f2);
System.out.println(read(f2).equals(s2));
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// Hash <i>f</i> by <i>md</i>
static String foo (File f, MessageDigest md) throws IOException {
FileInputStream fis = new FileInputStream(f);
DigestInputStream dis = new DigestInputStream(fis, md);
byte[] b = new byte[1024];
while (dis.read(b, 0, 1024) != -1) {
}
md = dis.getMessageDigest();
String s = new String(md.digest());
dis.close();
fis.close();
return s;
}
static void write (String s, File f) throws IOException {
FileWriter fw = new FileWriter(f);
BufferedWriter bw = new BufferedWriter(fw);
bw.write(s);
bw.newLine();
bw.close();
fw.close();
}
static String read (File f) throws IOException {
FileReader fr = new FileReader(f);
BufferedReader bf = new BufferedReader(fr);
String s;
s = bf.readLine();
bf.close();
fr.close();
return s;
}
This is your first problem:
String s = new String(md.digest());
You're creating a string with arbitrary binary data in the platform default encoding. It may well not be valid text data in the platform default encoding. In other words, you're losing data. Encode it with base-64 instead - that way you'll always have a string with ASCII characters, and can get back to the original binary data reliably.
Your second general problem is using FileReader and FileWriter. These always use the default platform encoding, which is a terrible API decision as it makes them almost useless in my view. You should almost always be specifying an encoding - I tend to use UTF-8. Use FileInputStream/FileOutputStream and InputStreamReader/InputStreamWriter to read/write text with files. (Or use the Guava helper routines.)
The digest value of the hashed file most likely contains a newline or line feed character (0x10 or 0x13) which breaks the way you read the string using BufferedReader.readLine().

Categories