Несколько замечаний:
Struct
для упаковки и распаковки заголовка unpack
должен быть методом класса, который принимает объект bytes
и возвращает экземпляр Packet
. __init__
. from dataclasses import dataclass
from typing import ClassVar
import struct
@dataclass
class Packet:
header : ClassVar[struct.Struct] = struct.Struct('????i')
payload: str
syn: bool = False
fin: bool = False
reset: bool = False
has_opt: bool = False
ack: int = 0
def pack(self):
return self.header.pack(
self.syn,
self.fin,
self.reset,
self.has_opt,
self.ack
) + self.payload.encode('utf-8')
@classmethod
def unpack(cls, data: bytes):
payload = data[cls.header.size]
syn, fin, reset, has_opt, ack = cls.header.unpack_from(data)
return Packet(
payload.decode('utf'),
syn,
fin,
reset,
has_opt,
ack)
Использовать Reader.read () . Возвращаемое значение -1 означает конец потока; иначе приведите к char .
Этот код считывает символьные данные из списка аргументов файла:
public class CharacterHandler {
//Java 7 source level
public static void main(String[] args) throws IOException {
// replace this with a known encoding if possible
Charset encoding = Charset.defaultCharset();
for (String filename : args) {
File file = new File(filename);
handleFile(file, encoding);
}
}
private static void handleFile(File file, Charset encoding)
throws IOException {
try (InputStream in = new FileInputStream(file);
Reader reader = new InputStreamReader(in, encoding);
// buffer for efficiency
Reader buffer = new BufferedReader(reader)) {
handleCharacters(buffer);
}
}
private static void handleCharacters(Reader reader)
throws IOException {
int r;
while ((r = reader.read()) != -1) {
char ch = (char) r;
System.out.println("Do something with " + ch);
}
}
}
Плохая вещь в приведенном выше коде состоит в том, что он использует набор символов системы по умолчанию. Везде, где возможно, предпочитайте известную кодировку (в идеале, кодировку Unicode, если у вас есть выбор). См. Charset класс для получения дополнительной информации. (Если вы чувствуете мазохизм, вы можете прочитать это руководство по кодированию символов .)
(Одна вещь, на которую вы могли бы обратить внимание, это дополнительные символы Юникода - те, которые требуют двух значений символов для Для получения более подробной информации см. класс Character , это крайний случай, который, вероятно, не будет применяться к домашней работе. )
Объединяя рекомендации от других по заданию кодировки символов и буферизации ввода, вот что я считаю довольно полным ответом.
Предполагая, что у вас есть объект File
представляющий файл, который вы хотите прочитать:
BufferedReader reader = new BufferedReader(
new InputStreamReader(
new FileInputStream(file),
Charset.forName("UTF-8")));
int c;
while((c = reader.read()) != -1) {
char character = (char) c;
// Do something with your character
}
Другой вариант - не читать символы по буквам - читать весь файл в память. Это полезно, если вам нужно смотреть на персонажей более одного раза. Один из тривиальных способов сделать это:
/** Read the contents of a file into a string buffer */
public static void readFile(File file, StringBuffer buf)
throws IOException
{
FileReader fr = null;
try {
fr = new FileReader(file);
BufferedReader br = new BufferedReader(fr);
char[] cbuf = new char[(int) file.length()];
br.read(cbuf);
buf.append(cbuf);
br.close();
}
finally {
if (fr != null) {
fr.close();
}
}
}
Обернуть входной поток в буферизованном считывателе, а затем использовать метод чтения для чтения одного байта за раз до конца потока.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Reader {
public static void main(String[] args) throws IOException {
BufferedReader buffer = new BufferedReader(
new InputStreamReader(System.in));
int c = 0;
while((c = buffer.read()) != -1) {
char character = (char) c;
System.out.println(character);
}
}
}
У вас есть несколько вариантов, если вы используете BufferedReader
. Этот буферизованный ридер работает быстрее, чем ридер, поэтому вы можете обернуть его.
BufferedReader reader = new BufferedReader(new FileReader(path));
reader.read(char[] buffer);
это читает строку в массив символов. У вас есть похожие варианты. Посмотрите документацию.
Wrap your reader in a BufferedReader, which maintains a buffer allowing for much faster reads overall. You can then use read() to read a single character (which you'll need to cast). You can also use readLine() to fetch an entire line and then break that into individual characters. The BufferedReader also supports marking and returning, so if you need to, you can read a line multiple times.
Generally speaking, you want to use a BufferedReader or BufferedInputStream on top of whatever stream you are actually using since the buffer they maintain will make multiple reads much faster.