Nano Hash - криптовалюты, майнинг, программирование

Двоичный файл не читается должным образом в Java

Я пытаюсь прочитать двоичный файл на Java, используя метод bufferedReader. Я написал этот двоичный файл, используя кодировку «UTF-8». Код для записи в бинарный файл:

  byte[] inMsgBin=null;
  try {
      inMsgBin = String.valueOf(cypherText).getBytes("UTF-8");
      //System.out.println("CIPHER TEXT:FULL:BINARY WRITE: "+inMsgBin);
  } catch (UnsupportedEncodingException ex) {
      Logger.getLogger(EncDecApp.class.getName()).log(Level.SEVERE, null, ex);
  }
  try (FileOutputStream out = new FileOutputStream(fileName+ String.valueOf(new SimpleDateFormat("yyyyMMddhhmm").format(new Date()))+ ".encmsg")) {
      out.write(inMsgBin);
      out.close();
  } catch (IOException ex) {
      Logger.getLogger(EncDecApp.class.getName()).log(Level.SEVERE, null, ex);
  }       


System.out.println("cypherText charCount="+cypherText.length());

Здесь 'cypherText' - это строка с некоторым содержимым. Общее количество символов, записанных в файле, равно 19. Также после записи, когда я открываю двоичный файл в Notepad ++, он показывает некоторые символы. Всего при выборе всего содержимого файла считается 19 символов.

Теперь, когда я читаю тот же файл с помощью BufferedReader, используя следующие строки кода:

try
        {
        DecMessage obj2= new DecMessage();
          StringBuilder cipherMsg=new StringBuilder();

            try (BufferedReader in = new BufferedReader(new FileReader(filePath))) {
                String tempLine="";
                fileSelect=true;
                while ((tempLine=in.readLine()) != null) {                      
                    cipherMsg.append(tempLine);
                }
            }

System.out.println("FROM FILE: charCount= "+cipherMsg.length());

Здесь общее количество прочитанных символов (хранящихся в 'charCount') равно 17 вместо 19.

Как я могу правильно прочитать все символы файла?

21.04.2014

  • Я не вижу, чтобы вы устанавливали UTF-8 где-нибудь в коде чтения... 21.04.2014
  • Что такое cyperText? Это строка UTF-8? Если это не так... тогда кодировка не будет работать с Java, отбрасывая недопустимые последовательности байтов и заменяя их заполнителем (и cypherText является String... почему вы конвертируете его в byte[] записать в файл? ) 21.04.2014
  • это все то же самое. Я пробовал с помощью try (BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(filePath),UTF8))) 21.04.2014
  • @DecodingLife, что такое UTF8? это UTF-8. Для стандартов вы можете использовать StandardCharsets.UTF_8 . Я попробовал ваш код, он работает очень хорошо после добавления UTF_8 . 21.04.2014
  • @BrianRoach - для шифротекста не установлено значение UTF-8. Спасибо за то же самое. Не могли бы вы помочь мне установить кодировку UTF-8, поскольку я не могу этого сделать. 21.04.2014
  • @DecodingLife что такое cypherText? Как он определяется и создается? 21.04.2014
  • @BrianRoach - cypherText - это строковая переменная, которая используется для хранения символов ascii 8-битных двоичных последовательностей. Предположим, что «10001000» — это 8-битная двоичная последовательность, программа получает ее эквивалентный символ ASCII и добавляет к cypherText с помощью простого оператора конкатенации. 22.04.2014

Ответы:


1

Укажите ту же кодировку при чтении файла.

   try (final BufferedReader br = Files.newBufferedReader(new File(filePath).toPath(),
                    StandardCharsets.UTF_8))

ОБНОВИТЬ

Теперь у меня есть твоя проблема. Спасибо за файл.

Опять же: ваш файл по-прежнему доступен для чтения любым средством чтения текста, например Notepad ++ (поскольку ваши символы включают расширенные и управляющие символы, вы видите эти нечитаемые символы, но они все еще в ASCII).

Теперь вернемся к вашей проблеме. У вас есть две проблемы с вашим кодом.

  1. При чтении файла вы должны указать правильную кодировку. Читатели - это читатели символов - байты будут преобразованы в символы при чтении. Если вы укажете набор символов, он будет использовать его, иначе он будет использовать системный набор символов по умолчанию. Итак, вы должны создать BufferedReader следующим образом

    try (final BufferedReader br = Files.newBufferedReader(новый файл(filePath).toPath(), StandardCharsets.UTF_8))

  2. Во-вторых, у вас есть персонажи, которые включают управляющие символы. при чтении файла построчно, по умолчанию bufferedReader использует системные символы EOL по умолчанию и пропускает эти символы. вот почему вы получаете 17 вместо 19 (поскольку у вас есть 2 символа CR). Чтобы избежать этой проблемы, вы должны читать символы.

    инт ч; while ((ch = br.read()) > -1) { buffer.append((char)ch); }

В целом приведенный ниже метод вернет правильный текст.

static String readCyberText() {
        StringBuilder buffer = new StringBuilder();
        try (final BufferedReader br = Files.newBufferedReader(new File("C:\\projects\\test2201404221017.txt").toPath(),
                StandardCharsets.UTF_8)){
            int ch;
            while ((ch = br.read()) > -1) {
                buffer.append((char)ch);
            }
            return buffer.toString();
        }
        catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }

И вы можете протестировать

String s = readCyberText();
    System.out.println(s.length());
    System.out.println(s);

и вывод как

19
ia@

m©Ù6ë<«9K()il

Примечание: длина строки составляет 19, однако при ее отображении отображается только 17 символов. потому что консоль считается eof и отображается в другой строке. но строка содержит все 19 символов правильно.

21.04.2014
  • @ассилиас . Да Files.readAllLines вернет List‹String› . Для этого варианта использования мы можем использовать этот метод. Но его следует использовать с осторожностью, чтобы избежать проблем с памятью для больших файлов. 21.04.2014
  • @Mani - Спасибо за подробную помощь, Мани, но я все еще сталкиваюсь с той же проблемой. Можете ли вы помочь мне установить кодировку по умолчанию на UTF_8 для всех строк. 21.04.2014
  • @DecodingLife - Что вы имели в виду, установив кодировку UTF_8 для всех строк? . С какой проблемой вы столкнулись. Вам нужно предоставить больше кода, чтобы понять проблему, если проблема не в опубликованном коде. Настройка Charset должна происходить до запуска JVM, иначе она не вступит в силу. 21.04.2014
  • @Mani - я разрабатываю зашифрованный текст, используя свой собственный алгоритм. Я пишу файл в кодировке UTF-8, чтобы он не ошибся в разных системах, поскольку система может иметь кодировку по умолчанию Java, Windows или любую другую кодировку. Теперь, как показано на графике -BrianRoach- (см. его комментарии выше), это может быть связано с тем, что CypherText не находится в кодировке UTF_8. Я не уверен на 100% в правильности его мнения, но все же хочу попробовать и это. 21.04.2014
  • @Mani - И содержимое cypherText создается следующим образом: возьмите 8-битную двоичную последовательность (например, 10010001) и преобразуйте ее в эквивалентный символ ASCII, а затем добавьте полученную строку в строковую переменную с именем cypherText. Я пишу содержимое в двоичном режиме, чтобы сделать его нечитаемым для всех, кто открывает файл, содержащий содержимое cypherText. 21.04.2014
  • @DecodingLife - Как вы конвертируете двоичную последовательность (байт) в символ ASCII? и когда вы говорите добавить? как вы добавляете (используя +? или любой StringBuffer.append?). если возможно опубликуйте наш код. Причина в том, что имеет значение, как сформировался ваш шифротекст. 22.04.2014
  • @Мани - String a="10101001"; cypherText+=(char)obj1.asc(a);. Функция asc работает отлично, поэтому вам не нужно беспокоиться о ее работе и возвращении Integer. Поскольку максимальное значение, предлагаемое строкой a, может быть только 11111111, что равно 2 ^ 8-1, которое отлично хранится в переменной Integer, так что это также не будет проблемой. 22.04.2014
  • @Mani - значение, содержащееся в String a выше, является просто примером. 22.04.2014
  • @DecodingLife - я пытался смоделировать то, что вы делаете. но все же работает нормально. смотрите обновление. попробуй это выполнить. 22.04.2014
  • Почему вы делаете String.valueOf(cyberText), когда CyberText уже является строкой? 22.04.2014
  • @Mani - Думаю, есть проблема с чтением файлов. Когда я открываю файл в Notepad++ после его записи в двоичном режиме, я вижу следующее содержимое: ia@ m©Ù6ë<«9K()il. Здесь вы можете видеть вторую строку... она заполнена каким-то символом, и если подсчитать все, то получится 19 символов. 22.04.2014
  • @Mani - Когда я читаю содержимое файла с помощью буферизованного считывателя, я думаю, что он пропускает вторую строку (символы второй строки выглядят просто пустыми, но на самом деле занимают какой-то символ), и, следовательно, общее количество прочитанных символов составляет всего 17 и не 19, потому что он не может прочитать вторую строку, содержащую 2 символа. Я могу сказать, что вторая строка (которая кажется пустой, содержит 2 символа, потому что при выборе этой строки в Notepad++ в строке состояния редактора говорится, что выбрано 2 символа). Я не знаю, как я могу поделиться файлом с вами здесь. 22.04.2014
  • @Mani – dropbox.com/s/uuppgtobn9c66cl/test2201404221017.encmsg проверьте этот файл и откройте его в блокноте++. Проверьте вторую строку файла. 22.04.2014
  • @Brian Roach - взгляните на файл, который я получаю после записи в двоичном режиме. dropbox.com/s/uuppgtobn9c66cl/test2201404221017.encmsg 22.04.2014
  • @Mani - На самом деле в файле есть два последовательных возврата каретки. При чтении, поскольку буферизованный считыватель читает строку только до тех пор, пока он не получит \n, поэтому я думаю, что он пропускает эти две строки. Можете ли вы предложить решение для этого? 22.04.2014
  • @DecodingLife - я обновил свой ответ на основе ваших комментариев 23.04.2014
  • @Mani - Большое спасибо. Я просто искал это, но не думал о том, чтобы долгое время держаться подальше от Java. Благодаря тонну. 24.04.2014
  • @DecodingLife . Добро пожаловать - Рад узнать, что ваша проблема решена :) 24.04.2014
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

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

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..