2010-10-31 23 views
5

Estoy codificando una clase que compara los archivos de dos directorios mediante la comparación de las matrices de Byte de cada archivo. Sin embargo, no estoy obteniendo los resultados esperados; los archivos idénticos no se están resolviendo como archivos idénticos.Comparación de archivos mediante Byte Array issues

Primer problema:

Coincidencia de los archivos byte [] con los iguales() resuelve falsa a juego con archivos (marcados con un único archivo como para eludir el posible problema índice de desalineación; el cheque todavía resuelve en falso.) .

Segundo problema:

Cuando se utiliza de Vector containsAll() para comprobar que tanto los vectores de partido byte [] (un vector por directorio con el byte [] para cada archivo) da como resultado esta verificación en falso, incluso con directorios idénticos (Esta verificación se ha eliminado del código a continuación). Entonces, ¿hay un problema con la forma en que estoy alineando los dos vectores? (He comprobado esto usando dos directorios con los archivos coincidentes en el mismo orden cargados en las sangres que coinciden, esto todavía resulta en una falta de coincidencia de Vector).

Tercer problema:

Cuando hay subdirectorios en los directorios que se comprueba un archivo es lanzado indica que se deniega el acceso no se encuentra una excepción. ¿Por qué está pasando esto? ¿Cómo puedo eludir esto? No quiero verificar los archivos contenidos en los subdirectorios, pero estoy diseñando el código para que el usuario final no tenga que preocuparse por los subdirectorios de los directorios que se comparan. Esto solo ocurre cuando hay subdirectorios, funciona bien cuando no hay subdirectorios en los directorios que se controlan.

Ejemplo Excepción:

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) 

Aquí está el código:

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

Carpeta de archivo2 = new File (workingDir1); - ¿Es eso un error tipográfico? – EboMike

+0

Sí, que se supone que es un error tipográfico "File folder2 = new File (workingDir2);" Voy a verificar si funciona ahora. Gracias por la noticia. – TheWolf

Respuesta

5

La función equals no está haciendo una comparación profunda, en lugar de un byte[] que está comparando direcciones. En su lugar, debe utilizar

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

para realizar la comparación profunda de las matrices de bytes.

Más detalles en Arrays.equals.

En cuanto a su tercera pregunta, en realidad no está filtrando solo los archivos. Al iterar a través de imprimir el nombre del archivo que debe construir el vector de almacenamiento de los archivos:

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

Usted, por supuesto, tiene que hacer esto para fileArr2 y fileVec2 también.

+0

Gracias, funciona ahora. ¿Conoces la solución al tercer problema? – TheWolf

+0

Sí, funciona bien cuando no hay subdirectorios en los directorios que se comparan. – TheWolf

+0

@Vapen: no está filtrando directorios, filtéelos de la misma forma que imprime (vea las ediciones en mi respuesta). –

4

Simple. El método equals(Object) en una matriz se hereda de Object, y por lo tanto es equivalente al operador ==; es decir, es solo una comparación de referencia.

Esto se especifica en JLS 6.4.5.

Si quiere comparar matrices por valor, use los métodos java.util.Arrays.equals(array1, array2). Hay sobrecargas para matrices de cada tipo primitivo y matrices de Object.

(Tenga en cuenta que se trata de la semántica de la aplicación de cada tipo de elemento de equals método que determina si Arrays.equals(Object[], Object[]) es una o comparación "profunda" "superficial".)

SEGUIMIENTO

Sospecho que el tercer problema ocurre porque su aplicación está tratando de abrir el subdirectorio como un archivo. Eso no funcionará En lugar de ello, es necesario:

  1. Uso File.isFile() y File.isDirectory() para determinar si usted debe leer las entradas de directorio como archivos o dirctories (o en absoluto).
  2. Para un directorio, debe recursivamente usar File.listFiles() o similar para iterar sobre el contenido del subdirectorio.
+0

Gracias, funciona ahora. ¿Ustedes conocen la solución al tercer problema? – TheWolf