我的任务是编写两个Java程序。一个程序创建一个名为“ userinput.txt”的文件,然后将用户输入的所有内容写入该文件。完成后,将创建一个名为“ Checksum.txt”的新文件,该文件将在读取其中的内容后记下“ userinput.txt”文件的校验和。
第二个程序只读取相同的'userinput.txt'文件,然后生成校验和并将其打印到控制台上(我还必须让程序读取另一个checksum.txt文件并将其显示在控制台中以进行比较这两个,但我还没有解决这个问题。
我为这两个程序编写了程序,但是我的问题是,即使它们正在读取同一文件,它们也是不同的校验和。我使用的是Adler32,但是CRC32也给了我两个不同的校验和(控制台上的校验和总是与checksum.txt中存储的校验和不同),而且我不确定是什么原因导致了坦白:/
这里是接受用户输入并生成校验和文件的代码:
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);
}
}
}
读取文件并在控制台中生成校验和的代码:
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());
}
}
请学习如何使用调试器,请参见What is a debugger and how can it help me diagnose problems?。
话虽如此,您的代码有一些问题。首先,您要在一个空数组上计算校验和。当你写:
byte readBuffer[] = new byte[buffer.length];
cis.read(readBuffer);
您正在读取buffer
数组大小的空数组。您不需要创建新的数组。实际上,由于存在内容,因此您应该阅读已经拥有的buffer
数组。在这种情况下,您只需编写:
cis.read(buffer);
下一个问题是您正在使用用于文本/字符串文件的读取器和写入器,但是校验和/哈希算法通常在字节级别上起作用。这可能会导致一些错误,例如编码(ASCII,UTF-8等)和行终止问题(\n
与\r\n
与\r
)。
但是,在这种情况下,您正在使用readLine()
。此方法最后不返回行终止符,请参见the documentation of readLine()
:
返回:
包含行内容的字符串,不包括任何行终止符;如果已到达流的末尾,则为null
因此,您从文件中读取的内容与文件中的实际上有所不同。但是您的readLine()
类在已保存的文件中读取每个字节(应如此)。假设您仅输入字符串CheckSum
。您的第一个计算将在3字节长的数组上运行,其值如下:
"abc"
[97,98,99]
方法将忽略行终止符,但它仍存在于文件中。当您使用第二个程序检查校验和时,正在使用的readLine()
将显示以下字节:
InputStream
(最后的字节取决于您使用的操作系统)
如您所见,您在不同的字节数组上运行校验和,从而导致不同的校验和值。因此,请确保对相同的字节数组内容(或[97,98,99,10]
内容)运行校验和检查,以在两个应用程序中获得相同的校验和。