Сравнение файлов через проблемы с байтовым массивом - PullRequest
5 голосов
/ 31 октября 2010

Я кодирую класс, который сравнивает файлы двух каталогов, сравнивая байтовые массивы каждого файла.Я, однако, не получаю ожидаемых результатов;идентичные файлы не разрешаются как идентичные файлы.

Первая проблема:

Сопоставление файлов Byte [] с equals () преобразуется в false с соответствующими файлами (проверяется только одним файлом для обходавозможная проблема смещения индекса; проверка по-прежнему разрешается в false.).

Вторая проблема:

При использовании Vector hasAll () для проверки соответствия обоих векторов байта [] (один вектор накаталог с байтом [] для каждого файла) эта проверка приводит к ложному, даже с идентичными каталогами (эта проверка была удалена из кода ниже.).Так есть ли проблема с тем, как я выровняю два вектора?(Я проверил это с использованием двух каталогов с соответствующими файлами в том же порядке, загруженными в соответствующие индексы; это все еще приводит к несоответствию вектора).

Третья проблема:

При наличии подкаталогов вдля проверяемых каталогов выдается исключение файла, в котором указано, что доступ запрещен.Почему это происходит?Как я могу обойти это?Я не хочу проверять файлы, содержащиеся в подкаталогах, но я разрабатываю код так, чтобы конечному пользователю не нужно было беспокоиться о подкаталогах сравниваемых каталогов.Это происходит только тогда, когда есть подкаталоги, и работает нормально, когда в проверяемых каталогах нет подкаталогов.

Пример исключения:

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)

Вот код:

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;
    }
}

Ответы [ 2 ]

5 голосов
/ 31 октября 2010

Функция equals не проводит глубокого сравнения, скорее, для byte[] вы сравниваете адреса.Вместо этого вы должны использовать

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

для глубокого сравнения массивов байтов.

Подробнее о Arrays.equals .

Что касаетсяВаш третий вопрос, вы на самом деле не фильтруете только файлы.Когда вы выполняете итерацию, чтобы распечатать имя файла, вы должны создать вектор, хранящий файлы:

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

Вы, конечно, должны будете сделать это и для fileArr2 и fileVec2.

4 голосов
/ 31 октября 2010

Simple. Метод equals(Object) в массиве наследуется от Object и, следовательно, эквивалентен оператору ==; то есть это просто эталонное сравнение.

Это указано в JLS 6.4.5 .

Если вы хотите сравнить массивы по значению, используйте методы java.util.Arrays.equals(array1, array2). Существуют перегрузки для массивов каждого примитивного типа и массивов Object.

(Обратите внимание, что семантика реализации каждого типа элемента метода equals определяет, является ли Arrays.equals(Object[], Object[]) "глубоким" или "поверхностным" сравнением.)

СЛЕДУЙТЕ ЗА

Я подозреваю, что третья проблема возникает из-за того, что ваше приложение пытается открыть подкаталог в виде файла. Это не сработает. Вместо этого вам необходимо:

  1. Используйте File.isFile() и File.isDirectory(), чтобы определить, должны ли вы читать записи каталога как файлы или каталоги (или не делать их вообще).
  2. Для каталога вы должны рекурсивно использовать File.listFiles() или аналогичный для перебора содержимого подкаталога.
...