首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Adler32生成的校验和与.txt文件校验和不匹配

Adler32生成的校验和与.txt文件校验和不匹配
EN

Stack Overflow用户
提问于 2020-03-22 04:56:37
回答 1查看 287关注 0票数 0

我的任务是编写两个java程序。一个程序创建一个名为“userinput.txt”的文件,然后将用户输入的所有内容写入文件。一旦完成,将创建一个名为“Checksum.txt”的新文件,该文件将在读取“userinput.txt”文件中的内容后写下“userinput.txt”文件的校验和。

第二个程序只是读取相同的'userinput.txt‘文件,然后生成一个校验和并将其打印到控制台上(我还必须让程序读取另一个checksum.txt文件并在控制台中显示它以比较这两个文件,但我还没有考虑到这一点)。

Iv为这两个程序编写了程序,但我的问题是,它们都是不同的校验和,尽管它们读取的是同一个文件。我正在使用Adler32,但CRC32也给了我两种不同的校验和(控制台上的校验和总是与存储在checksum.txt中的校验和不同),我不确定是什么导致了它:/

下面是接受用户输入并生成校验和文件的代码:

代码语言:javascript
复制
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);
        }
    }

}

读取文件并在控制台中生成校验和的代码:

代码语言:javascript
复制
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());


   }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-03-22 10:53:34

请了解如何使用调试器,请参阅What is a debugger and how can it help me diagnose problems?

也就是说,您的代码有一些问题。首先,计算空数组上的校验和。当你写:

代码语言:javascript
复制
byte readBuffer[] = new byte[buffer.length];
cis.read(readBuffer);

您正在读取与buffer数组大小相同的空数组。您不需要创建一个新的数组。实际上,您应该读取您已经拥有的buffer数组,因为有您的内容。在这种情况下,您只需写:

代码语言:javascript
复制
cis.read(buffer);

下一个问题是,您使用的是用于文本文件/字符串文件的读取器和写入器,但是校验和/散列算法通常在字节级别上工作。这可能导致一些错误,如编码(ASCII、UTF-8等)和行终止问题(\n\r\n\r)。

但是,在本例中,您正在使用readLine()。此方法不返回结束时的行终止,请参阅the documentation of readLine()

返回:

一个字符串,包含行的内容,不包括任何行终止字符,或者如果到达流的末尾,则为null。

因此,您从文件中读取的内容与文件中的实际内容并不相同。但是您的CheckSum类读取保存文件中的每个字节的(正如它应该的那样)。假设您只输入字符串"abc"。第一次计算将在3个字节长的数组上运行,其值如下:

代码语言:javascript
复制
[97,98,99]

readLine()方法忽略了行终止,但它仍然存在于文件中。当您使用第二个程序检查校验和时,您使用的InputStream将看到以下字节:

代码语言:javascript
复制
[97,98,99,10]

(最后的字节取决于您正在使用的操作系统)

如您所见,您在不同的字节数组上运行校验和,从而产生不同的校验和值。因此,确保您正在对相同的字节数组内容(或InputStream内容)运行校验和检查,以在两个应用程序中获得相同的校验和。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60796077

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档