#java #java.util.scanner
#Ява #java.util.сканер
Вопрос:
Мне нужно проверить каждый символ в файле и привести его к байту. Но, к сожалению, сканер не дает никаких возможностей не разбивать последний символ строки… Я пытаюсь сделать что-то вроде этого :
Scanner in = new Scanner(new File(path)); Listlt;Bytegt; byteList = new ArrayListlt;gt;(); while (in.hasNextLine()) { String a = in.nextLine(); if (in.hasNextLine()) { a = a (char) (13); } for (char c : a.toCharArray()) { byteList.add((byte) c); } } byte[] bytes = new byte[byteList.size()]; for (int i = 0; i lt; byteList.size(); i ) { bytes[i] = byteList.get(i); } return bytes; }
Может быть, у вас есть какие-нибудь идеи по решению этой проблемы ? Я буду благодарен вам за помощь.
Комментарии:
1. Так что не используйте сканер, используйте FileInputStream.
Ответ №1:
Вы не можете сделать это с Scanner.readLine()
помощью или BufferedReader.readLine()
потому, что оба этих API используют разделители строк.
Возможно, вы могли бы сделать это Scanner.next()
с помощью пользовательского регулярного выражения разделителя, которое заставляет разделители строк включаться в токены. (Подсказка: используйте взгляд сзади.)
Однако для того, что вы на самом деле делаете в коде, было бы лучше либо a, FileInputStream
либо a FileReader
.
Это подводит меня к другому вопросу.
Что должен делать этот код?
На самом деле он преобразует кодовые единицы Юникода в байты, отбрасывая верхние биты. Это могло бы иметь смысл, если бы входная кодировка была ASCII или (возможно) ЛАТИНСКОЙ-1. Но для всего остального это, вероятно, исказит текст.
- Если вы пытаетесь прочитать файл как (необработанные) байты, просто используйте
FileInputStream
BufferedInputStream
. Затем считайте / обрабатывайте байты напрямую. Терминаторы линий не потребуют какого — либо специального обращения. - Если вы пытаетесь прочитать файл как закодированные символы в какой-либо кодировке и транслитерировать его в другую (например, ASCII). Вы должны писать на
FileWriter
BufferedWriter
. Еще раз символы разделителя строк / терминатора будут сохранены … и вы можете «нормализовать» их, если захотите. - Если вы делаете что-то другое … ну, это, вероятно, неправильный способ сделать это. A
Listlt;Bytegt;
будет неэффективным и трудным для преобразования во что-то, с чем другие API Java могут иметь дело напрямую.
Ответ №2:
Прочитайте весь файл, включая все окончания строк, в виде одной строки:
String fileStr = in.useDelimiter("\A").next();
Регулярное выражение A
соответствует началу ввода, которое никогда не встречается, поэтому возвращается весь входной поток next()
.
Если ваша ситуация требует, чтобы все окончания строк были исправлены до определенного конца строки, независимо от того, что содержит файл, сделайте это:
fileStr = fileStr.replaceAll("\R", "n");
Регулярное выражение R
соответствует всем типам окончаний строк.
Конечно, все это можно сделать в виде 1 строки:
String fileStr = in.useDelimiter("\A").next().replaceAll("\R", "n");