im tasked with written two java programs. One program creates a file called 'userinput.txt', then writes everything the user inputs into the file. Once done a new file is created called 'Checksum.txt' and this file will write down the checksum for the 'userinput.txt' file after reading whats inside of it.
The 2nd program just reads the same 'userinput.txt' file and then generates a checksum and prints it onto the console (i also have to get the program to read the other checksum.txt file and display it int the console to compare the two but i havent gotten around to that yet).
Iv written the program for these two but my problem is they are both different checksum even though they are reading the same file. Im using Adler32 but CRC32 also gives me two different checksums (the one on console is always different to the one stored in checksum.txt) and im not sure whats causing it frankly :/
Here is the code that takes userinput and generates the checksum file:
package attemp2;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.ByteArrayInputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Scanner;
import java.util.zip.Adler32;
import java.util.zip.CheckedInputStream;
public class main {
public static void main(String[] args) throws IOException {
System.out.println("All inputs will be recorded into a sigle file. Enter 'x' when done. A checksum File will aslo be created at the end");
FileWriter fw = new FileWriter("d:/input.txt", false); // clears previous entry in file.
while (true) {
Scanner input = new Scanner(System.in); //get user input
String ch = input.nextLine(); //stores user input
System.out.println(ch); //prints out what user just inputed
if (ch.equals("x")) { //stops running if 'x' is entered
break;
}
BufferedWriter writer = new BufferedWriter(new FileWriter("d:/input.txt", true));
writer.write(ch);
writer.newLine(); // Add new line
writer.close();
}
try {
FileReader reader = new FileReader("d:/input.txt");
BufferedReader br = new BufferedReader(reader);
// read line by line String line;
String read = "";
String line;
while ((line = br.readLine()) != null) {
read = read + line;
//prints out text in file currently
System.out.println(line);
}
//checksum.txt generation
byte buffer[] = read.getBytes();
ByteArrayInputStream bais = new ByteArrayInputStream(buffer);
CheckedInputStream cis = new CheckedInputStream(bais, new Adler32());
byte readBuffer[] = new byte[buffer.length];
cis.read(readBuffer);
FileOutputStream out = new FileOutputStream("d://checksum.txt");
BufferedWriter wrt = new BufferedWriter(new FileWriter("d:/checksum.txt", false));
wrt.write(Long.toString(cis.getChecksum().getValue()));
wrt.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
The code that reads the file and generates a checksum in console:
package check;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Scanner;
import java.util.zip.Adler32;
public class CheckSum {
private Adler32 checksum;
private String filepath;
InputStream inputStream;
public CheckSum(String filepath) throws FileNotFoundException{
this.filepath = filepath;
checksum = new Adler32();
inputStream = new FileInputStream(filepath);
}
public long generateChecksum() throws IOException{
int c;
while((c = inputStream.read())!=-1){
checksum.update(c);
}
return checksum.getValue();
}
public void read() throws IOException{
File file = new File(filepath);
BufferedReader br = new BufferedReader(new FileReader(file));
String st;
while ((st = br.readLine()) != null) {
System.out.println(st);
}
}
public static void main(String[] args) throws Exception{
Scanner scanner = new Scanner(System.in);
String filepath = "d:/input.txt";
CheckSum checksum = new CheckSum(filepath);
checksum.read();
System.out.println("For the file: "+filepath);
System.out.println("The checksum generated is: "+checksum.generateChecksum());
}
}
Please learn how to use a debugger, see What is a debugger and how can it help me diagnose problems?.
That being said, you have some problems with your code. First you are calculating the checksum on an empty array. When you write:
byte readBuffer[] = new byte[buffer.length];
cis.read(readBuffer);
you are reading an empty array of the size of the buffer
array. You don't need to create a new array. In fact, you should read the buffer
array you already have, since there is your content. In this case you just write:
cis.read(buffer);
The next problem is that you are using readers and writers, which are used for text/string files, but checksum/hash algorithm usually works on byte level. This can result in several errors like encoding (ASCII, UTF-8, etc. stuff) and line-termination issues (\n
vs. \r\n
vs. \r
).
However, in this case you are working with readLine()
. This method does not return the line-termination at the end, see the documentation of readLine()
:
Returns:
A String containing the contents of the line, not including any line-termination characters, or null if the end of the stream has been reached
So, what you are reading from the file is not the same what is actually in the file. But your CheckSum
class reads every byte in the saved file (as it should). Assume you enter only the string "abc"
. Your first calculation will be run on the 3 bytes long array with the values:
[97,98,99]
The line-termination is ignored by the readLine()
method, but it is still present in the file. When you check the checksum with the second program, the InputStream
you are using will see the following bytes:
[97,98,99,10]
(The bytes at the end depends on the OS you are using)
As you see you run the checksum on different byte arrays, resulting in different checksum values. So, make sure you are running the checksum checks on the same byte array content (or InputStream
content) to get the same checksum in both applications.