English 中文(简体)
通过字节数组问题进行文件比较
原标题:File Comparison via Byte Array issues

我正在编写一个类,通过比较每个文件的Byte数组来比较两个目录的文件。然而,我没有得到预期的结果;相同的文件没有被解析为相同的文件。

第一个问题:

匹配文件Byte[]with equals()在匹配的文件中解析为false(仅使用一个文件进行检查以避免可能的索引未对齐问题;该检查仍解析为false)。

第二个问题:

当使用Vector s containsAll()检查Byte[]的两个Vector是否匹配(每个目录一个Vector,每个文件有Byte[])时,即使在相同的目录下,此检查也会导致错误(此检查已从下面的代码中删除。)。那么,我对齐两个向量的方式有问题吗?(我已经用两个目录检查了这一点,这两个目录中的匹配文件以相同的顺序加载到匹配的indeces中;这仍然会导致Vector不匹配)。

第三个问题:

当正在检查的目录中有子目录时,会引发一个未找到文件的异常,说明访问被拒绝。为什么会发生这种情况?我该如何规避这一点?我不想检查子目录中包含的文件,但我正在设计代码,以便最终用户不必担心要比较的目录的子目录。只有当有子目录时才会发生这种情况,当被检查的目录中没有子目录时,它可以正常工作。

异常示例:

Byte reading error!
Byte reading error!
java.io.FileNotFoundException: C:Dir1Dir2Dir3Dir4SubDir (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:Dir1Dir2Dir3Dir4SubDir 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)

这是代码:

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("
Working Directory 1 Files
");
            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("
Working Directory 2 Files
");
            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!
Continue 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;
    }
}
最佳回答

equals函数并没有进行深入比较,而是对byte[]进行地址比较。相反,您应该使用

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

以执行字节数组的深度比较。

有关数组。等于

至于你的第三个问题,你实际上并不是只过滤文件。当您迭代以打印出文件名时,您应该构建存储文件的Vector:

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

当然,对于fileArr2fileVec2

问题回答

易于理解的数组上的equals(Object)方法继承自Object,因此等效于==运算符;即它只是一个参考比较。

这在JLS 6.4.5

如果要按值比较数组,请使用java.util.arrays.equals(array1,array2)方法。每个基元类型的数组和<code>Object</code>的数组都有重载。

(请注意,正是equals方法的每个元素类型实现的语义决定了Arrays.equals(Object[],Object[])是“深层”还是“浅层”比较。)

跟进

我怀疑发生第三个问题是因为您的应用程序试图将子目录作为文件打开。那行不通。相反,您需要:

  1. Use File.isFile() and File.isDirectory() to determine whether you should be reading the directory entries as files or dirctories (or not at all).
  2. For a directory, you should recursively use File.listFiles() or similar to iterate over the subdirectory contents.




相关问题
Spring Properties File

Hi have this j2ee web application developed using spring framework. I have a problem with rendering mnessages in nihongo characters from the properties file. I tried converting the file to ascii using ...

Logging a global ID in multiple components

I have a system which contains multiple applications connected together using JMS and Spring Integration. Messages get sent along a chain of applications. [App A] -> [App B] -> [App C] We set a ...

Java Library Size

If I m given two Java Libraries in Jar format, 1 having no bells and whistles, and the other having lots of them that will mostly go unused.... my question is: How will the larger, mostly unused ...

How to get the Array Class for a given Class in Java?

I have a Class variable that holds a certain type and I need to get a variable that holds the corresponding array class. The best I could come up with is this: Class arrayOfFooClass = java.lang....

SQLite , Derby vs file system

I m working on a Java desktop application that reads and writes from/to different files. I think a better solution would be to replace the file system by a SQLite database. How hard is it to migrate ...