Как я могу читать символы до определенного в Java?
Я хочу прочитать несколько слов из файла. Я не нашел никакого способа сделать это, поэтому я решил читать символ за символом, но мне нужно остановиться на пробелах, чтобы сохранить прочитанное слово в моем массиве и перейти к следующему.
Я делаю приложение внешней сортировки, поэтому у меня есть ограничение памяти, и, в этом случае, я не могу просто использовать readLine()
а потом split()
Мне нужно иметь контроль над тем, что я читаю.
read()
Метод возвращает Int, и я понятия не имею, что я могу сделать, чтобы read()
метод возвращает символ и прекращает чтение после пробела.
Это мой код так далеко:
protected static String [] readWords(String arqName, int amountOfWords) throws IOException {
FileReader arq = new FileReader(arqName);
BufferedReader lerArq = new BufferedReader(arq);
String[] words = new String[amountOfWords];
for (int i = 0; i < amountOfWords; i++){
//words[i] = lerArq.read();
}
return words;
}
Редактировать 1: я использовал сканер и next()
метод, это сработало. Инициализация сканера на главной.
static String [] readWords(int amountOfWords, Scanner leitor) throws IOException {
String[] words= new String[amountOfWords];
for (int i = 0; i < amountOfWords; i++){
words[i] = leitor.next();
}
return words;
}
2 ответа
Если вы хотите читать это символ за символом (чтобы иметь больше контроля над тем, что вы хотите хранить, а что нет), вы можете попробовать что-то вроде этого:
import java.io.BufferedReader;
import java.io.IOException;
[...]
public static String readNextWord(BufferedReader reader) throws IOException {
StringBuilder builder = new StringBuilder();
int currentData;
do {
currentData = reader.read();
if(currentData < 0) {
if(builder.length() == 0) {
return null;
}
else {
return builder.toString();
}
}
else if(currentData != ' ') {
/* Since you're talking about words, here you can apply
* a filter to ignore chars like ',', '.', '\n', etc. */
builder.append((char) currentData);
}
} while (currentData != ' ' || builder.length() == 0);
return builder.toString();
}
А потом назовите это так:
String[] words = new String[amountOfWordsToRead];
for (int i = 0; i < amountOfWordsToRead; i++){
words [i] = readNextWord(yourBufferedReader);
}
Может быть, это будет полезно.
Это не проблема для использования read()
, Просто приведите результат к персонажу:
...
for (int i = 0; i < memTam; i++) {
// this should work. you will get the actual character
int current = lerArq.read();
if (current != -1) {
char c = (char) current;
// then you can do what you need with this character
}
}
...
Метод возвращает чтение символа в виде целого числа в диапазоне от 0 до 65535 или -1, если достигнут конец потока.
Я не буду добавлять много теории о кодировках, как это делается в Java и т. Д., Потому что я не знаю некоторых деталей очень низкого уровня. У меня есть общее понимание того, как это работает.
С каждой клавишей на клавиатуре связан номер. Каждый введенный вами символ можно перевести в десятичное число. Например, A
становится числом 65
, Это стандарт, и он признан во всем мире.
На данный момент, я надеюсь, вы можете согласиться, что это не так странно, что read()
метод возвращает число, а не фактический символ:)
Существует нечто, называемое таблицей ASCII, которая представляет все эти коды (цифры) для всех клавиш на вашей клавиатуре.
Вот только чтобы показать, как это выглядит:
Dec Char Dec Char Dec Char Dec Char
--------- --------- --------- ----------
0 NUL (null) 32 SPACE 64 @ 96 `
1 SOH (start of heading) 33 ! 65 A 97 a
2 STX (start of text) 34 " 66 B 98 b
3 ETX (end of text) 35 # 67 C 99 c
4 EOT (end of transmission) 36 $ 68 D 100 d
5 ENQ (enquiry) 37 % 69 E 101 e
6 ACK (acknowledge) 38 & 70 F 102 f
7 BEL (bell) 39 ' 71 G 103 g
8 BS (backspace) 40 ( 72 H 104 h
9 TAB (horizontal tab) 41 ) 73 I 105 i
10 LF (NL line feed, new line) 42 * 74 J 106 j
11 VT (vertical tab) 43 + 75 K 107 k
12 FF (NP form feed, new page) 44 , 76 L 108 l
13 CR (carriage return) 45 - 77 M 109 m
14 SO (shift out) 46 . 78 N 110 n
15 SI (shift in) 47 / 79 O 111 o
16 DLE (data link escape) 48 0 80 P 112 p
17 DC1 (device control 1) 49 1 81 Q 113 q
18 DC2 (device control 2) 50 2 82 R 114 r
19 DC3 (device control 3) 51 3 83 S 115 s
20 DC4 (device control 4) 52 4 84 T 116 t
21 NAK (negative acknowledge) 53 5 85 U 117 u
22 SYN (synchronous idle) 54 6 86 V 118 v
23 ETB (end of trans. block) 55 7 87 W 119 w
24 CAN (cancel) 56 8 88 X 120 x
25 EM (end of medium) 57 9 89 Y 121 y
26 SUB (substitute) 58 : 90 Z 122 z
27 ESC (escape) 59 ; 91 [ 123 {
28 FS (file separator) 60 < 92 \ 124 |
29 GS (group separator) 61 = 93 ] 125 }
30 RS (record separator) 62 > 94 ^ 126 ~
31 US (unit separator) 63 ? 95 _ 127 DEL
Итак, представьте, что у вас есть .txt
файл с некоторым текстом - все буквы имеют соответствующие цифры.
Проблема с ASCII состоит в том, что ASCII определяет 128 символов, которые отображаются на цифры 0–127 (все буквы верхнего регистра, буквы нижнего регистра, цифры 0–9 и еще несколько символов).
Но в мире есть еще много разных символов / символов (разные алфавиты, эмодзи и т. Д.), Поэтому для их представления должна быть другая система кодирования.
Это называется Unicode. Unicode - это то же самое для символов, чьи коды 0-127. Но в целом Unicode может представлять гораздо более широкий диапазон символов.
На Яве char
тип данных (и, следовательно, значение, которое Character
инкапсуляции объектов) основаны на оригинальной спецификации Unicode, в которой символы определены как 16-битные объекты фиксированной ширины. Вы можете проверить более подробную информацию в этом Javadoc. Другими словами, все строки в Java представлены в UTF-16.
Надеюсь, после этой длинной истории, есть смысл, почему вы получаете числа при чтении, но вы можете привести их к типу char
, И опять же, это просто своего рода обзор высокого уровня. Удачного кодирования:)