Как отделить inputStream от последовательного порта?

Я читаю данные из последовательного порта, используя InputStream.

Одну часть потока мне нужно преобразовать в String, а другую в бинарные данные.

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

Мой вопрос: могу ли я каким-то образом разделить поток, чтобы получить все данные двумя методами за одну отправку с последовательного порта?

private static void readingBytesSN(SerialPort comPort) {

    comPort.addDataListener(new SerialPortDataListener() {
        @Override
        public int getListeningEvents() {
            return SerialPort.LISTENING_EVENT_DATA_AVAILABLE;
        }

        @Override
        public void serialEvent(SerialPortEvent serialPortEvent) {

            InputStream in;

            String startSn2 = "110000010011010001101100100011011000100011010000111000010001010";
            String newLine2 = "01100000110110010001101100010001101000011100001000101";

            String startSn = "27434877273598525669";
            String newLine = "12273598525669";
            String endOfSn = "12694954545053565052661310";
            String endOfData = "1227513232131032131032131032131032131027109275132";


            String s1 = "";
            String s2 = "";

            if (serialPortEvent.getEventType() != SerialPort.LISTENING_EVENT_DATA_AVAILABLE) {
                return;
            }

            int x = 0;
            try {

                in = comPort.getInputStream();

                Scanner sc = new Scanner(in);

                List<String> line = new ArrayList<>();

                while (sc.hasNextLine()) {
                    line.add(sc.next());
                    if (line.contains("\u001Bm\u001B3")) {
                        break;
                    }
                }

                while (((x = in.read()) != 109)) {
                    s1 += String.format("%8s", Integer.toBinaryString(x & 0xFF)).replace(' ', '0');
                }
            } catch (IOException e1) {
                e1.printStackTrace();
            }

            String[] snArray = s1.split(startSn2);
            

            for (int i = 1; i < snArray.length; i++) {

                BufferedImage img = new BufferedImage(1, 1, BufferedImage.TYPE_BYTE_BINARY);
                Graphics2D g2d = img.createGraphics();
                Font font = new Font("Arial", Font.PLAIN, 2);
                g2d.setFont(font);
                int height = g2d.getFontMetrics().getHeight();
                g2d.dispose();

                img = new BufferedImage(384, 40, BufferedImage.TYPE_INT_RGB);
                g2d = img.createGraphics();

                g2d.setFont(font);
                g2d.setColor(Color.WHITE);
                int fontSize = 1;

                for (String line : snArray[i].split(newLine2)) {

                    g2d.drawString(line, 0, height);
                    height += fontSize;
                    //System.out.println("Serial number: " + line);
                }
                //g2d.dispose();
                try {
                    ImageIO.write(img, "png", new File("images\\Text" + i + ".png"));
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
                g2d.dispose();

                String result = null;
                try {
                    result = SerialOcr("images\\Text" + i + ".png");
                } catch (TesseractException e) {
                    e.printStackTrace();
                }
                System.out.println(result);

            }
        }
    });

}

Пожалуйста, опубликуйте свой код до сих пор

g00se 30.12.2022 12:30

Это может быть сложно. Я не думаю, что это обязательно правильный подход к чтению «строк» ​​с помощью Scanner, а затем просто продолжать чтение основного входного потока. Я думаю, вам лучше сбросить все содержимое входного потока в файл (не пытайтесь читать String - только байты), а затем опубликовать ссылку на него, чтобы я правильно посоветовал. Вы можете использовать try (InputStream in = comPort().getInputStream()) { in.transferTo(Files.newOutputStream(Path.of("data.bin"))); } catch(Throwable t) { t.printStackTrace(); }

g00se 30.12.2022 15:19

Вот файл который я получил с вашим кодом ссылка

Danilo Djurovic 30.12.2022 20:29

Отличная работа. я взгляну

g00se 30.12.2022 20:39

На первый взгляд, никакой код после того, как вы закончили читать строки, не будет выполняться, поскольку "\u001Bm\u001B3" завершает ввод. Под «вводом» (и до дальнейшего уведомления) я имею в виду содержимое файла, который вы мне дали. Вероятно, будет хорошей идеей, если вы выделите синтаксический анализ в отдельный метод с прототипом, таким как private void parse(InputStream in). Это упростит при тестировании ввод данных из файла вместо последовательного порта.

g00se 30.12.2022 20:54

Проблема в том, что когда я нажимаю «Печать» на устройстве, оно отправляет данные, а сканер выполняет свою работу по сбору текстовых данных. Другая часть кода while (((x = in.read()) != 109)) выполняет работу по получению изображений, и все это работает отлично, за исключением того, что мне нужно нажать «Печать» два раза, чтобы весь код выполнился.

Danilo Djurovic 30.12.2022 21:47

Хорошо. В этом случае вам нужно было нажать ее дважды, чтобы создать файл. Без программирования, вам нужно нажимать его дважды?

g00se 30.12.2022 22:08

Когда я нажимаю «Печать», я получаю все данные, которые мне нужны, но они расходуются сканером, и мне нужно нажать еще раз, чтобы использовать их в цикле while. Я всегда получаю одни и те же текущие данные при печати. Я отправил ответ о том, как мне удалось заставить его работать, может быть, у вас есть предложение получше?

Danilo Djurovic 31.12.2022 19:15

Что это за железо - какое-то метеорологическое устройство?

g00se 31.12.2022 19:39
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
2
9
53
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я повторил входной поток, используя этот код.

InputStream bufferdInputStream = new BufferedInputStream(myInputStream);

bufferdInputStream.mark(some_value);
//do the first method
bufferdInputStream.reset();
//do the second method

Я был бы более склонен просто прочитать все в byte[], тогда вы сможете обработать это

g00se 31.12.2022 19:41

В настоящее время я использую его с приведенным выше кодом, но я также попробую с вашим предложением. Теперь я пытаюсь показать индикатор выполнения при получении данных с устройства, но у меня проблемы с отображением правильного прогресса. Но, думаю, я задам еще один вопрос по этому поводу. Большое спасибо еще раз.

Danilo Djurovic 05.01.2023 22:33

Другие вопросы по теме