2010-10-31 10 views
5

Sto codificando una classe che confronta i file di due directory confrontando gli array Byte di ciascun file. Tuttavia, non sto ottenendo i risultati attesi; i file identici non vengono risolti come file identici.Confronto file tramite problemi di matrice di byte

Primo problema:

corrispondente ai file byte [] con equals() risolve su false con i file corrispondenti (controllato con un solo file come per aggirare il possibile problema indice di disallineamento, il controllo si risolve ancora su false.) .

Secondo problema:

Quando si utilizza di Vector containsAll() per controllare che entrambi i vettori di byte [] partita (un vettore per directory con Byte [] per ogni file) risultati di questa controllo nella false anche con le directory identici (Questo controllo è stato rimosso dal codice qui sotto.). Quindi c'è un problema con il modo in cui sto allineando i due vettori? (L'ho verificato usando due directory con i file corrispondenti nello stesso ordine caricati in indie corrispondenti, che si risolve comunque in una mancata corrispondenza Vector).

Terzo problema:

Quando ci sono le sottodirectory nelle directory da controllare un file non trovato viene generata un'eccezione che indica che l'accesso è negato. Perché sta succedendo? Come posso eludere questo? Non voglio controllare i file contenuti nelle sottodirectory, ma sto progettando il codice in modo che l'utente non debba preoccuparsi delle sottodirectory delle directory confrontate. Questo accade solo quando ci sono sottodirectory, funziona bene quando non ci sono sottodirectory nelle directory controllate.

Esempio Eccezione:

Byte reading error! 
Byte reading error! 
java.io.FileNotFoundException: C:\Dir1\Dir2\Dir3\Dir4\SubDir (Access is denied) 
    at java.io.FileInputStream.open(Native Method) 
    at java.io.FileInputStream.<init>(Unknown Source) 
    at tools.filesystem.filecomparison.FileComparator.getBytes(FileComparator.java:166) 
    at tools.filesystem.filecomparison.FileComparator.main(FileComparator.java:102) 
java.io.FileNotFoundException: C:\Dir1\Dir2\Dir3\Dir4\SubDir Files (Access is denied) 
    at java.io.FileInputStream.open(Native Method) 
    at java.io.FileInputStream.<init>(Unknown Source) 
    at tools.filesystem.filecomparison.FileComparator.getBytes(FileComparator.java:166) 
    at tools.filesystem.filecomparison.FileComparator.main(FileComparator.java:111) 

Ecco il codice:

package tools.filesystem.filecomparison; 

import java.io.File; 
import java.io.FileInputStream; 
import java.io.IOException; 
import java.io.InputStream; 
import java.util.Scanner; 
import java.util.Vector; 

public class FileComparator 
{ 
    public static void main(String[] args) 
    { 
     String workingDir1 = ""; 
     String workingDir2 = ""; 

     File[] fileArr1 = null; 
     File[] fileArr2 = null; 

     Vector<File> fileVec1 = new Vector<File>(); 
     Vector<File> fileVec2 = new Vector<File>(); 

     Scanner console = new Scanner(System.in); 
     while (true) 
     { 
      System.out.println("Enter working directory one . . . ."); 
      workingDir1 = console.nextLine(); 
      workingDir1.replace("\\", "\\\\"); 

      System.out.println("Enter working directory two . . . ."); 
      workingDir2 = console.nextLine(); 
      workingDir2.replace("\\", "\\\\"); 

      File folder1 = new File(workingDir1); 
      File[] listOfFiles1 = folder1.listFiles(); 

      File folder2 = new File(workingDir1); 
      File[] listOfFiles2 = folder2.listFiles(); 

      fileArr1 = listOfFiles1; 
      fileArr2 = listOfFiles2; 

      System.out.println("\nWorking Directory 1 Files\n"); 
      for (int i = 0; i < listOfFiles1.length; i++) 
      { 
       if (listOfFiles1[i].isFile()) 
       { 
        System.out.println(" " + listOfFiles1[i].getName()); 
       } 
/*    else if (listOfFiles1[i].isDirectory()) 
       { 
        System.out.println("Directory " + listOfFiles1[i].getName()); 
       }*/ 
      } 

      System.out.println("\nWorking Directory 2 Files\n"); 
      for (int i = 0; i < listOfFiles2.length; i++) 
      { 
       if (listOfFiles2[i].isFile()) 
       { 
        System.out.println(" " + listOfFiles2[i].getName()); 
       } 
/*    else if (listOfFiles2[i].isDirectory()) 
       { 
        System.out.println("Directory " + listOfFiles2[i].getName()); 
       }*/ 
      } 

      for (File fle : fileArr1) 
      { 
       fileVec1.add(fle); 
      } 

      for (File fle : fileArr2) 
      { 
       fileVec2.add(fle); 
      } 

      if (fileVec1.containsAll(fileVec2)) 
       break; 
      else 
      { 
       System.out.println("Directories do not contain the same files!\nContinue anyways? y/n?"); 
       if (console.nextLine().equalsIgnoreCase("y")) 
        break; 
       else if (console.nextLine().equalsIgnoreCase("n")) 
        continue; 
      } 
     } 

     Vector<Vector<File>> alignedVectors = align(fileVec1, fileVec2); 

     fileVec1 = alignedVectors.elementAt(0); 
     fileVec2 = alignedVectors.elementAt(1); 

     Vector<byte[]> fileByteVect1 = new Vector<byte[]>(); 
     Vector<byte[]> fileByteVect2 = new Vector<byte[]>(); 
     try 
     { 
      fileByteVect1 = getBytes(fileVec1); 
     } 
     catch (IOException e) 
     { 
      System.out.println("Byte reading error!"); 
      e.printStackTrace(); 
     } 
     try 
     { 
      fileByteVect2 = getBytes(fileVec2); 
     } 
     catch (IOException e) 
     { 
      System.out.println("Byte reading error!"); 
      e.printStackTrace(); 
     } 

     boolean[] check = new boolean[fileByteVect1.capacity()]; 

     int i1 = 0; 
     //debug 
     for (byte[] e : fileByteVect1) 
     { 
      System.out.println("Vector 1 count " + i1); 
      System.out.println(e.toString()); 
      for (byte b : e) 
      { 
       System.out.print(b + " "); 
      } 
      i1++; 
     } 

     int i2 = 0; 
     //debug 
     for (byte[] e : fileByteVect2) 
     { 
      System.out.println("Vector 2 count " + i2); 
      System.out.println(e.toString()); 
      for (byte b : e) 
      { 
       System.out.print(b + " "); 
      } 
      i2++; 
     } 

     if (fileByteVect1.size() == fileByteVect2.size()) 
     { 
      System.out.println(fileByteVect1.size()); 
      for (int i = 0; i < fileByteVect1.size(); i++) 
      { 
       if (fileByteVect1.elementAt(i).equals(fileByteVect2.elementAt(i))) 
       { 
        check[i] = true; 
        System.out.println("File at index " + i + " are identical"); 
       } 
       else 
       { 
        check[i] = false; 
        System.out.println("File at index " + i + " are not identical"); 
       } 
      } 
     } 
     else 
      System.out.println("Files do not match!"); 
    } 

    public static Vector<Vector<File>> align(Vector<File> fileVect1, Vector<File> fileVect2) 
    { 
     Vector<Vector<File>> mainBuffer = new Vector<Vector<File>>(); 
     Vector<File> bufferFileVect = new Vector<File>(); 
     for (File fle1 : fileVect1) 
     { 
      for (File fle2 : fileVect2) 
      { 
       if (fle1.getName().equals(fle2.getName())) 
        bufferFileVect.add(fle2); 
      } 
     } 

     mainBuffer.add(fileVect1); 
     mainBuffer.add(bufferFileVect); 

     return mainBuffer; 
    } 

    public static Vector<byte[]> getBytes(Vector<File> fileVector) throws IOException 
    { 
     Vector<byte[]> outVector = new Vector<byte[]>(); 

     for (File file : fileVector) 
     { 
      InputStream is = new FileInputStream(file); 

      // Get the size of the file 
      long length = file.length(); 

      if (length > Integer.MAX_VALUE) 
      { 
       System.out.println("File is too large!"); 
      } 

      // Create the byte array to hold the data 
      byte[] bytes = new byte[(int) length]; 

      // Read in the bytes 
      int offset = 0; 
      int numRead = 0; 
      while (offset < bytes.length && (numRead = is.read(bytes, offset, bytes.length - offset)) >= 0) 
      { 
       offset += numRead; 
      } 

      // Ensure all the bytes have been read in 
      if (offset < bytes.length) 
      { 
       throw new IOException("Could not completely read file " + file.getName()); 
      } 

      // Close the input stream and return bytes 
      outVector.add(bytes); 
      is.close(); 
     } 
     return outVector; 
    } 
} 
+1

File folder2 = new File (workingDir1); - è un errore? – EboMike

+0

Sì, si tratta di un refuso che dovrebbe essere "File folder2 = new File (workingDir2);" Vado a controllare se funziona ora. Grazie per l'avviso. – TheWolf

risposta

5

La funzione equals non sta facendo un confronto profondo, piuttosto per un byte[] si sta confrontando gli indirizzi. Invece dovresti usare

Arrays.equals(fileByteVect1.elementAt(i), fileByteVect2.elementAt(i)) 

per eseguire il confronto approfondito degli array di byte.

Maggiori dettagli su Arrays.equals.

Per quanto riguarda la terza domanda, in realtà non stai filtrando solo per i file. Quando si scorre attraverso di stampare il nome del file si dovrebbe costruire il vettore la memorizzazione dei file:

for (File fle : fileArr1) { 
    if (fle.isFile()) { 
     fileVec1.add(fle); 
     System.out.println(" " + fle.getName()); 
    } 
} 

Sarà, ovviamente, hanno a che fare questo per fileArr2 e fileVec2 pure.

+0

Grazie, ora funziona. Conoscete la soluzione al terzo problema? – TheWolf

+0

Sì, funziona correttamente quando non ci sono sottodirectory nelle directory confrontate. – TheWolf

+0

@Vapen: non stai filtrando le directory, le filtra nello stesso modo in cui stampi (vedi le modifiche alla mia risposta). –

4

Semplice. Il metodo equals(Object) su una matrice viene ereditato da Object e quindi equivale all'operatore ==; cioè è solo un confronto di riferimento.

Specificato in JLS 6.4.5.

Se si desidera confrontare gli array in base al valore, utilizzare i metodi java.util.Arrays.equals(array1, array2). Esistono sovraccarichi per le matrici di ciascun tipo e matrici primitive di Object.

(Si noti che è la semantica di attuazione equals metodo che determina se Arrays.equals(Object[], Object[]) è un "profonda" o confronto "superficiale" di ciascun tipo di elemento.)

follow up

sospetto che il terzo problema si verifica perché l'applicazione sta tentando di aprire la sottodirectory come file. Quello non funzionerà. Invece, è necessario:

  1. Usa File.isFile() e File.isDirectory() per determinare se si dovrebbe essere la lettura delle voci di directory come file o dirctories (o per niente).
  2. Per una directory, si dovrebbe ricorsivamente uso File.listFiles() o simile per scorrere i contenuti sottodirectory.
+0

Grazie, ora funziona. Ragazzi, conoscete la soluzione al terzo problema? – TheWolf