Попытка прочитать двоичный файл как текст, но сканер останавливается на первой строке

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

public static void main(String[] args) throws IOException
{

    Scanner readF = new Scanner(new File("D:\\CurrentDatabase_372.txt"));
    String line = null;
    String newLine = System.getProperty("line.separator");
    FileWriter writeF = new FileWriter("D:\\Songs.txt");

    while (readF.hasNext())
    {
        line = readF.nextLine();

        if (line.contains("D:\\") && line.contains(".mp3"))
        {
            writeF.write(line.substring(line.indexOf("D:\\"), line.indexOf(".mp3") + 4) + newLine);
        }
    }

    readF.close();
    writeF.close();
}

The file starts like this:

pppppamepD:\Music\Korn\Untouchables\03     Blame.mp3pmp3pmp3pKornpMetalpKornpUntouchablespKornpUntouchables*;*KornpKornpKornUntouchables003pMetalKornUntouchables003pBlameKornUntouchables003pKornKornUntouchables003pMP3pppppCpppÀppp@ppøp·pppŸú#pdppppppòrSpUpppppp€ppªp8›qpppppppppppp,’ppÒppp’ÍpET?ppppppôpp¼}`Ñ#ãâK†¡H¤*(DppppppppppppppppuÞѤéú:M®$@]jkÝW0ÛœFµú½XVNp`w—wâÊp:ºŽwâÊpppp8Npdpp¡pp{)pppppppppppppppppyY:¸[ªA¥Bi   `Û¯pppppppppppp2pppppppppppppppppppppppppppppppppppp¿ÞpAppppppp€ppp€;€?€CpCpC€H€N€S€`€e€y€~p~p~€’€«€Ê€â€Hollow LifepD:\Musica\Korn\Untouchables\04 Hollow Life.mp3pmp3pmp3pKornpMetalpKornpUntouchablespKornpUntouchables*;*KornpKornpKornUntouchables004pMetalKornUntouchables004pHollow LifeKornUntouchables004pKornKornUntouchables004pMP3pppppCpppÀHppppppøp¸pppǺxp‰ppppppòrSpUpppppp€ppªp8›qpppppppppppp,’ppÒpppŠºppppppppppôpp¼}`Ñ#ãâK†¡H¤*(DpppppppppppppppppãG#™R‚CA—®þ^bN °mbŽ‚^¨pG¦sp;5p5ÓÐùšwâÊp
)ŽwâÊpppp8Npdpp!cpp{pppppppppppppppppyY:¸[ªA¥Bi `ۯǺxp‰pppppp2pppppppppppppppppppppppppppppppppppp¿

Я хочу извлечь направления файлов, например "D:\Music\Korn\Untouchables\03 Blame.mp3".


person lukthy    schedule 18.03.2011    source источник


Ответы (3)


Вы не можете использовать линейный сканер для чтения двоичных файлов. У вас нет гарантии, что в двоичном файле даже есть «строки», разделенные символами новой строки. Например, что бы сделал ваш сканер, если бы было ДВА файла, соответствующих шаблону "D:\.*.mp3" без промежуточной новой строки? Вы бы извлекли все между первым "D:\" и последним ".mp3" со всем мусором между ними. Извлечение имен файлов из потока без разделителей, подобного этому, требует другой стратегии.

Если бы я писал это, я бы использовал относительно простой распознаватель с конечным состоянием, который обрабатывает символы по одному. Когда он встречает «d», он начинает сохранять символы, проверяя каждый символ, чтобы убедиться, что он соответствует требуемому шаблону, заканчивая, когда он видит «3» в «.mp3». Если в какой-то момент он обнаруживает неподходящий символ, он перезагружается и продолжает поиск.

РЕДАКТИРОВАТЬ: Если файлы для обработки небольшие (менее 50 МБ или около того), вы можете загрузить весь файл в память, что упростит сканирование.

person Jim Garrison    schedule 18.03.2011
comment
когда я открываю файл в блокноте ++, он показывает номера строк, но я не уверен, что он разделяет файл по разделителям строк. Я попробую ваш метод и скажу вам, сработало ли это. Спасибо за Ваш ответ. - person lukthy; 18.03.2011
comment
Это абсолютно сработало!!.. Большое спасибо за совет!!.. Наконец-то я извлек все песни из бинарного файла. - person lukthy; 18.03.2011

Как уже было сказано, поскольку это двоичный файл, вы не можете использовать сканер или другие программы для чтения символов. Вы можете использовать обычный FileInputStream для чтения фактических необработанных байтов файла. Класс String в Java имеет конструктор, который берет массив байтов и преобразует их в строку. Затем вы можете искать в этой строке имена файлов. Это может работать, если вы просто используете набор символов по умолчанию.

Строка (байт []): http://download.oracle.com/javase/1.4.2/docs/api/java/lang/String.html FileInputStream для чтения байтов: http://download.oracle.com/javase/tutorial/essential/io/bytestreams.html

person Matt Crinklaw-Vogt    schedule 18.03.2011
comment
Спасибо за ссылку ReadingBytes!.. Я не знал, что вы можете читать файл побайтно. - person lukthy; 18.03.2011

Используйте hasNextLine() вместо hasNext() в проверке цикла while.

while (readF.hasNextLine()) {
 String line = readF.nextLine();
 //Your code
 }
person Piyush Mattoo    schedule 18.03.2011
comment
Спасибо за очень быстрый ответ! Я исправил это, но он все еще останавливается на первой строке. - person lukthy; 18.03.2011