Чтение определенных байтов из RandomAccessFile и проверка, равны ли они 0

первый раз плакат здесь. Заранее спасибо за просмотр моего вопроса. У меня куча проблем с домашним заданием, в котором я должен прочитать определенный диапазон байтов из RandomAccessFile, а затем проверить этот диапазон байтов, чтобы увидеть, равны ли они 0. Я просмотрел все в поисках чего-то, что относится к этому, но ничто из того, что я нашел, не попадает в точку. Любая оказанная помощь будет оценена.

Задача говорит нам о том, что существует некий файл, содержащий данные о гипотетических учениках школы. Каждый из этих учеников представлен 40 байтами кода, но первые четыре байта нашего файла должны быть целым числом с общим количеством учеников в школе (допустим, их 75). Байты с 4 по 43 представляют первого ученика (#0), 44-83 представляют второго (#1) и так далее. Когда учащийся переходит в другую школу, его 40 байт перезаписываются всеми нулями (символами).

Я написал метод под названием «transferStudent», который принимает строку, представляющую имя файла, и целое число, представляющее количество студентов. Если есть какие-либо исключения или если файл по какой-то причине не перезаписывает данные учащегося, я возвращаю false;

Вот моя работа на данный момент:

public static Boolean transferStudent(String fileName, int studentNum) {

    RandomAccessFile file = new RandomAccessFile(fileName, "rw");
    file.writeInt(75);
    try {
        if (studentNum == 0) {
            file.seek(4);
            file.writeBytes("0000000000000000000000000000000000000000"); // 40 zero characters
            file.seek(4);
            for (int i = 0; i < 40; i++) {
                if (file.read() == 0) {
                    return true;
                }
            }
            return false;
        }
        else if (studentNum > 0) {
            file.seek(4 + (studentNum * 40));
            file.writeBytes("0000000000000000000000000000000000000000"); // 40 more zeroes
            file.seek(4);
            for (int i = (4 + (studentNum * 40)); i < (44 + (studentNum * 40)); i++) {
                if (file.read() == 0) {
                    return true;
                }
            }
            return false;
        }
        else {
            return false;
        }
    }
    catch (Exception e) {
        return false;
    }
}

Всякий раз, когда я просматриваю созданный двоичный файл, в диапазоне, соответствующем studentNum, действительно есть 0. Однако консоль всегда выводит false — проверка почему-то не работает. Я на грани того, чтобы рвать на себе волосы из-за этого. Пожалуйста помоги!


person alex_crow    schedule 07.05.2014    source источник
comment
+1 Хорошо написанный вопрос. Спасибо.   -  person Jim Garrison    schedule 07.05.2014
comment
Зарегистрируйтесь на другом сайте SE (например, Super User или Server Fault), чтобы получить +100 репутации и доступ к основным функциям, таким как комментирование и голосование.   -  person Jim Garrison    schedule 07.05.2014


Ответы (2)


Вы путаете нули ASCII "0" с двоичными нулями. Вы пишете первое и тестируете второе. ASCII "0" занимает два байта. Обратите внимание, что «символ» и «байт» в Java не совпадают.

person user207421    schedule 07.05.2014
comment
Круто, спасибо за объяснение. Есть ли у вас какие-либо предложения относительно того, что я мог бы сделать, чтобы прочитать значения ASCII, равные 0? Возможно, вместо этого используйте file.readChar() == 0 при проверке файла? - person alex_crow; 07.05.2014
comment
Немного подправив свой код, я, наконец, заставил его работать. Еще раз спасибо за ваше разъяснение. Я отметил ваш ответ проверкой и дал вам +1, потому что он указал мне правильное направление. - person alex_crow; 07.05.2014

Итак, я думаю, что наконец-то понял проблему: как заявил EJP, я перепутал нули ASCII «0» с двоичными нулями. Как уже говорилось, нули ASCII занимают два байта информации. Это сбивало меня с толку и до сих пор сбивает с толку: я просматриваю записанный файл, но кажется, что для записи каждого «0» используется только один байт информации. Мне придется провести больше исследований по этой теме. Помимо этого, с моим кодом была еще одна проблема: каждый раз, когда я запускал программу, в файл записывались нулевые символы. С этим проблем не было, но была вторая проблема с проверкой — я ничего не делал для дальнейшего продвижения указателя файла при использовании цикла для проверки.

Итак, чтобы исправить мой код, нужно было сделать две вещи:

Во-первых, мне нужно было найти способ сдвинуть указатель файла так, чтобы каждое место в моем RandomAccessFile читалось правильно.

Во-вторых, я должен был проверить соответствующее значение при запуске моей проверки: это значение должно было быть «48», что является значением ASCII для символа «0».

Вот мой новый код:

public static boolean transferStudent(String fileName, int studentNum) throws IOException {

    RandomAccessFile file = new RandomAccessFile(fileName, "rw");
    boolean trueOrFalse = false;
    file.writeInt(75);
    try {
        if (studentNum == 0) {
            file.seek(4);
            file.writeBytes("0000000000000000000000000000000000000000"); // 40 zero characters
            file.seek(4);
            for (int i = 0; i < 40; i++) {
                file.seek(4 + i); // Here is where the file pointer is advanced in the for-loop - very crucial
                if (file.read() == 48) { // Here is where the file is checked for the appropriate value - the ASCII value for "0"
                    trueOrFalse = true;
                }
            }
            return trueOrFalse;
        }
        else if (studentNum > 0) {
            file.seek(4 + (studentNum * 40));
            file.writeBytes("0000000000000000000000000000000000000000"); // 40 more zeroes
            file.seek(4 + (studentNum * 40));
            for (int i = 0; i < 40; i++) { // The same happens here as above
                file.seek((4 + (studentNum * 40)) + i); // ... and here also
                if (file.read() == 48) {
                    trueOrFalse = true;
                }
            }
            return trueOrFalse;
        }
        else {
            return trueOrFalse;
        }
    }
    catch (Exception e) {
        return false;
    }
}
person alex_crow    schedule 07.05.2014
comment
Это все еще неправильно. Присваивание говорит о сорока байтах, а не о сорока символах. - person user207421; 08.05.2014