Как я читаю вход, познаковый в Java?

Несколько замечаний:

  1. Вы можете предварительно создать объект Struct для упаковки и распаковки заголовка
  2. Полезную нагрузку легче упаковать и распаковать отдельно. из шапки. Он может быть добавлен к упакованному заголовку и извлечен из пакета, используя нарезку.
  3. unpack должен быть методом класса, который принимает объект bytes и возвращает экземпляр Packet.
  4. Создание этого класса данных позволяет избежать написания большого количества шаблонов для метода __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)
46
задан Bill the Lizard 18 September 2012 в 17:05
поделиться

6 ответов

Использовать 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 , это крайний случай, который, вероятно, не будет применяться к домашней работе. )

58
ответ дан 26 November 2019 в 20:26
поделиться

Объединяя рекомендации от других по заданию кодировки символов и буферизации ввода, вот что я считаю довольно полным ответом.

Предполагая, что у вас есть объект 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
}
15
ответ дан 26 November 2019 в 20:26
поделиться

Другой вариант - не читать символы по буквам - читать весь файл в память. Это полезно, если вам нужно смотреть на персонажей более одного раза. Один из тривиальных способов сделать это:

  /** 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();
      }
    }
}
6
ответ дан 26 November 2019 в 20:26
поделиться

Обернуть входной поток в буферизованном считывателе, а затем использовать метод чтения для чтения одного байта за раз до конца потока.

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);          
        }       
    }   
}
6
ответ дан 26 November 2019 в 20:26
поделиться

У вас есть несколько вариантов, если вы используете BufferedReader . Этот буферизованный ридер работает быстрее, чем ридер, поэтому вы можете обернуть его.

BufferedReader reader = new BufferedReader(new FileReader(path));
reader.read(char[] buffer);

это читает строку в массив символов. У вас есть похожие варианты. Посмотрите документацию.

1
ответ дан 26 November 2019 в 20:26
поделиться

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.

1
ответ дан 26 November 2019 в 20:26
поделиться
Другие вопросы по тегам:

Похожие вопросы: