Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/396.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 散列中的字符串在输出到文件然后输入后不再相同_Java - Fatal编程技术网

Java 散列中的字符串在输出到文件然后输入后不再相同

Java 散列中的字符串在输出到文件然后输入后不再相同,java,Java,这是一件让我花了整整一天时间的奇怪事情: 如果用户将一个简单的字符串(如“1”)写入文件并立即读取,则获取的字符串等于原始字符串 但是,如果字符串是由某个哈希函数生成的,则获取的字符串将不再相同 下面的代码打印出true-false,我想知道幕后的诀窍 多谢各位 public static void main(String[] args) { try { String s1 = "1"; File f1 = new File("f1");

这是一件让我花了整整一天时间的奇怪事情:

如果用户将一个简单的字符串(如“1”)写入文件并立即读取,则获取的字符串
等于原始字符串

但是,如果字符串是由某个哈希函数生成的,则获取的字符串将不再相同

下面的代码打印出
true-false
,我想知道幕后的诀窍

多谢各位

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;
}
publicstaticvoidmain(字符串[]args){
试一试{
字符串s1=“1”;
文件f1=新文件(“f1”);
写入(s1,f1);
System.out.println(读取(f1).等于(s1));
MessageDigest md=MessageDigest.getInstance(“SHA-512”);
字符串s2=foo(新文件(“1.jpg”),md);
文件f2=新文件(“f2”);
写入(s2,f2);
System.out.println(读取(f2).等于(s2));
}捕获(无算法异常){
//TODO自动生成的捕捉块
e、 printStackTrace();
}捕获(IOE异常){
//TODO自动生成的捕捉块
e、 printStackTrace();
}
}
//通过md散列f
静态字符串foo(文件f,MessageDigest md)引发IOException{
FileInputStream fis=新的FileInputStream(f);
DigestInputStream dis=新的DigestInputStream(fis,md);
字节[]b=新字节[1024];
while(dis.read(b,0,1024)!=-1){
}
md=dis.getMessageDigest();
字符串s=新字符串(md.digest());
dis.close();
fis.close();
返回s;
}
静态无效写入(字符串s、文件f)引发IOException{
FileWriter fw=新的FileWriter(f);
BufferedWriter bw=新的BufferedWriter(fw);
bw.写入;
换行符();
bw.close();
fw.close();
}
静态字符串读取(文件f)引发IOException{
FileReader fr=新的FileReader(f);
BufferedReader bf=新的BufferedReader(fr);
字符串s;
s=bf.readLine();
bf.close();
fr.close();
返回s;
}

这是您的第一个问题:

String s = new String(md.digest());
您正在使用平台默认编码创建包含任意二进制数据的字符串。在平台默认编码中,它可能不是有效的文本数据。换句话说,您正在丢失数据。改为使用base-64编码-这样您将始终拥有一个包含ASCII字符的字符串,并且可以可靠地返回原始二进制数据


第二个常见问题是使用
FileReader
FileWriter
。它们总是使用默认的平台编码,这是一个可怕的API决策,因为在我看来,这使它们几乎毫无用处。您几乎应该总是指定一种编码——我倾向于使用UTF-8。使用
FileInputStream
/
FileOutputStream
InputStreamReader
/
InputStreamWriter
读取/写入包含文件的文本。(或使用番石榴助手例程。)

这是您的第一个问题:

String s = new String(md.digest());
您正在使用平台默认编码创建包含任意二进制数据的字符串。在平台默认编码中,它可能不是有效的文本数据。换句话说,您正在丢失数据。改为使用base-64编码-这样您将始终拥有一个包含ASCII字符的字符串,并且可以可靠地返回原始二进制数据


第二个常见问题是使用
FileReader
FileWriter
。它们总是使用默认的平台编码,这是一个可怕的API决策,因为在我看来,这使它们几乎毫无用处。您几乎应该总是指定一种编码——我倾向于使用UTF-8。使用
FileInputStream
/
FileOutputStream
InputStreamReader
/
InputStreamWriter
读取/写入包含文件的文本。(或使用Guava helper例程。)

哈希文件的摘要值很可能包含换行符或换行符(0x10或0x13),这会中断您使用
BufferedReader.readLine()读取字符串的方式。哈希文件的摘要值很可能包含换行符或换行符(0x10或0x13)这打破了您使用
BufferedReader.readLine()

读取字符串的方式。我想试试这个。谢谢。我想试试这个。谢谢。我认为这不是问题所在。在调试模式下,这两个字符串看起来是一样的,至少在我的特定情况下是一样的。谢谢。我认为这不是问题所在。在调试模式下,这两个字符串看起来是一样的,至少在我的特定情况下是一样的。非常感谢。