从目录中读取文件并在java中比较嵌套for循环中的文件

从目录中读取文件并在java中比较嵌套for循环中的文件,java,file,file-io,Java,File,File Io,在java中,从目录读取文件并比较嵌套for循环中的文件。第一个文件比较,但其余的说“不一样”,即使它是相同的。我知道我必须调整循环中的某些内容,以防止它发送空值或任何指针 File Directory = new File (location); File files[] = Directory.listFiles(); for (File f : files) { for (File g : files) { br = new

在java中,从目录读取文件并比较嵌套for循环中的文件。第一个文件比较,但其余的说“不一样”,即使它是相同的。我知道我必须调整循环中的某些内容,以防止它发送空值或任何指针

  File Directory = new File (location);
  File files[] = Directory.listFiles();

  for (File f : files)
  {   

     for (File g : files) 
     {
         br = new BufferedReader (new FileReader (f));
         while(( z = br.readLine()) != null)  s1+= z;

         br2 = new BufferedReader (new FileReader (g));   
         while ((y = br2.readLine()) != null) s2 += y;

         System.out.println();

      //     System.out.println(s1);   

      //   System.out.println(f.getName() + "=" + g.getName());

          if (s1.equals(s2)) {
         System.out.println(f.getName() + "=" + g.getName());
         System.out.println( "Content of both files are same");

     }
    else {
         System.out.println(f.getName() + "!=" + g.getName());
         System.out.println("Content of both files are not same"); 
     }

     }

您不断添加到相同的
s1
s2
,这意味着在前两个文件之后,您将始终在其中包含以前文件的内容。您可能希望在打开文件时清除它们

此外,您可能应该在外循环中移动
f
的读数。没有必要每次都读

还有其他方法可以加快速度,例如对每个文件的内容进行散列,然后在实际开始比较每对文件之前比较散列,或者更容易的是,首先比较文件的大小——两个文件的大小不同(例如
f.length()
g.length()
)永远都不会是原来的样子

(编辑以回答评论)

如果要删除两个完全相同的文件中的一个,可能需要遵循Windle的注释,以确保不会对同一对文件进行两次比较,然后如果
f
g
相同,则始终可以删除
f
。要删除文件,请使用

至于复制文件,您可以尝试查看以下内容:
要创建目标文件的名称,可以使用它。

我看不到任何地方声明了
s1
s2
。它们应该在内部foreach循环中声明。否则,您将把每个文件的内容连接到ses字符串中


您的算法效率很低,并且没有考虑新的行,但这是另一回事。

我已尝试修改您的解决方案以保持正确和快速。试试这个

StringBuffer s1 = new StringBuffer();
StringBuffer s2 = new StringBuffer();
for (int i = 0 ; i < files.length ; i++ )
 {   
     File f = files[i];
     s1 = new StringBuffer();
     br = new BufferedReader (new FileReader (f));
     while(( z = br.readLine()) != null)  s1.append(z);


  for (int j = i+1 ; j < files.length ; j++ )
    {
File g = files[j]  ;         
     s2 = new StringBuffer();
     br2 = new BufferedReader (new FileReader (g));   
     while ((y = br2.readLine()) != null) s2.append(y);

     System.out.println(" ");

     if (s1.equals(s2)) {
        System.out.println(f.getName() + "=" + g.getName());
        System.out.println( "Content of both files are same");

        // To write file to a new directory pass the new path and the file as String to the method as given below.
        writeToFile(newPath, s2);

        // To delete the file use the below statement.
        g.delete();
                 }
    else {
        System.out.println(f.getName() + "!=" + g.getName());
       System.out.println("Content of both files are not same"); 
     }

 }



 private void writeToFile(String fileName, String data) throws IOException{
     FileWriter fstream = new FileWriter(fileName);
      BufferedWriter out = new BufferedWriter(fstream);
      out.write(data);
      out.flush();
      out.close();
}
StringBuffer s1=新的StringBuffer();
StringBuffer s2=新的StringBuffer();
对于(int i=0;i
让我们举个例子。假设目录中有4个文件:
A
B
C
D

代码试图做的是将
位置
中的每个文件与同一目录中的每个文件进行比较

这意味着
A
A
B
C
D
比较
B
A
B
C
D

在本例中,发现文件相等的唯一情况是将
A
A
进行比较,
B
B
进行比较

因此,在这里进行的总共
16
比较中,
4
将导致文件相等,而其余文件则标记为不相等


因此,您应该期望更多的“不相同”输出,而不是“相同”输出。

您不断向s1和s2添加行,一旦找到第一个不相同的文件,s1和s2将不再相同。
此外,这种连接没有真正的必要,为什么不一次比较两行,在不相等的第一行中断并返回false呢?

这是不正确的。您错过了一个错误,即
s1
s2
在需要时不能重置。这意味着这“有效”只要文件相同,但一旦存在与前一个文件不匹配的文件,则始终返回false。请查看所有其他答案。这解释了为什么OP会找到更多“不相同”的输出。OP在理解上存在一个问题,即他们应该只期望“相同”输出。查找bug是下一步,其他人已经做得很好了。如果代码按照预期工作,使用示例文件,您将看到4个“相同”输出最少。如果有文件实际上是重复的,那么这个数字会增加。四个答案已经指出了这个错误,所以我只想评论一下我的一个不满:请不要在这里使用
foreach
样式循环。它很懒,而且效率很低。如果你有文件
f1、f2、f3
你的代码比较es
f1
f1、f2、f3
,然后
f2
f1、f2、f3
然后
f3
f1、f2、f3
。9个比较中有6个是无意义的。它们要么将文件与自身进行比较,要么只切换到
s1
s2
。列表越长,进行的比较就越糟糕。替换ur循环使用
for(int i=0;它在只需要N/2的情况下仍然进行N次比较。为什么要将A与B进行比较,将B与A进行比较?而且它仍然在循环中使用字符串连接,这会破坏性能。我理解字符串连接的问题。但是如何才能