0

从目录中读取文件并在 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"); 
     }

     }
4

5 回答 5

4

You keep adding to the same s1 and s2, which means after the first couple of files you'll always have the previous files' contents in there. You'd probably want to clear them when you open the files.

Also, you should probably move the reading of f in the outer loop. There's no point reading it every time.

There are other ways to make this faster, for instance hashing the contents of each file, and then comparing hashes before actually starting to compare each pair of files, or more easily, comparing the sizes of the files first -- two files having different sizes (as given by e.g. f.length() and g.length()) will never be the same.

(Editing to answer comment)

If you want to delete one of two identical files, you might want to follow Windle's comment to make sure you never compare the same pair of files twice, and then you can always delete f if f and g are the same. To delete a file, use File.delete().

As for copying files, you can try looking at this: Standard concise way to copy a file in Java? To create the name of the destination file, you can use this constructor.

于 2013-02-28T14:14:25.760 回答
2

我在任何地方都没有看到s1s2宣布。它们应该在内部 foreach 循环中声明。否则,您会将每个文件的内容连接到 ses 字符串中。

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

于 2013-02-28T14:16:22.620 回答
1

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

于 2013-02-28T14:32:02.067 回答
1

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

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();
}
于 2013-02-28T14:19:58.900 回答
0

让我们举这个例子。假设您在目录中有4 个文件:AB和.CD

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

这意味着AABC进行比较DBABCD进行比较。

在此示例中,发现文件相等的唯一情况A是与比较ABB..比较

因此,在16这里发生的全部比较中,4其中的文件将导致文件相等,而其余的则被标记为不相等。

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

于 2013-02-28T14:27:55.273 回答