Как правильно сохранить поток байтов в файл в Java / Scala? Как исправить неправильно сохраненный поток? - PullRequest
0 голосов
/ 01 ноября 2019

Story

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

Пример

Историю проблемы можно объяснить в следующем простомпример.

Допустим, у меня есть поток случайных чисел во входном файле randomInput.bin. Я буду имитировать поток случайных чисел, поступающих от аппаратного устройства RNG, отправив входной файл на стандартный вывод через cat. Я нашел два способа сохранить этот поток в файл:

A) Безопасный метод сохранения

Этот метод дает мне точно исходный поток случайных байтов.

import scala.sys.process._
import java.io.File

val res = ("cat randomInput.bin" #> new File(outputFile))!

B) Метод сохранения, приводящий к повреждению

К сожалению, это оригинальный метод сохранения, который я выбрал.

import scala.sys.process._
import java.io.PrintWriter

val randomBits = "cat randomInput.bin".!!

val out = new PrintWriter(outputFile)
out.println(randomBits)
if (out != null) {
  out.close()
  Seq("chmod", "600", outputFile).!
}

Файл, сохраненный с использованием метода B) , все еще является двоичнымоднако он примерно в 2 раза больше файла, сохраненного методом A) . Дальнейший анализ показывает, что поток случайных битов значительно меньше случайных.

Резюме

Я подозреваю, что метод сохранения B) добавляет что-то почти к каждому байту, однакопонимание этого лежит в основе моего опыта в Java / Scala I / O.

Я был бы очень признателен, если бы кто-нибудь объяснил мне разницу в низком уровне между методами A) и B) . Цель состоит в том, чтобы отменить изменения, созданные методом сохранения B) и получить исходный поток случайных байтов.

Заранее большое спасибо!

Ответы [ 2 ]

0 голосов
/ 01 ноября 2019

После консультации с @ kaya3 я изучил файлы. Вот фрагменты списка xxd обоих типов файлов.

A) Безвредный метод сохранения

0021df40: 02c3 c2e0 ec27 a1a7 85e5 295e a25e f3f8  .....'....)^.^..
0021df50: 4f2e 9fd3 f995 301f 546d fe28 69c8 233e  O.....0.Tm.(i.#>
0021df60: c514 4c32 a87f d3be 028c 1083 1bc6 4933  ..L2..........I3
0021df70: 643b 93a2 8b7c 5945 0198 307b 533a 12ea  d;...|YE..0{S:..
0021df80: 0c8a 00c9 c9c7 235e 1e7e 0814 7d8b 7aea  ......#^.~..}.z.
0021df90: 69f5 c30f b2ea 0e69 2441 b9f0 5f1b 6d13  i......i$A.._.m.
0021dfa0: 5cd8 b2ff 7e84 479e 06a2 7a55 fb95 4af3  \...~.G...zU..J.
0021dfb0: e4bc e919 1708 d37b b366 d40f 6a25 58f4  .......{.f..j%X.
0021dfc0: 627d 9664 da1f 9e08 dc92 ffc1 2b3f d1c9  b}.d........+?..
0021dfd0: d94d 980e 948e 9ae3 19ac 10c1 8a7c ecf6  .M...........|..

B) Метод сохранения, приводящий к повреждению

Этот список содержитмножество последовательностей efbf или bfbd - похоже, что есть основной сигнал bd ef bf, между которым смешиваются другие вещи. Похоже ли что-нибудь из этого на некоторые пробелы, вставленные Writer ?

003d5500: bd0f efbf bd2f 3aef bfbd 5fef bfbd efbf  ...../:..._.....
003d5510: bdef bfbd d187 4800 36ef bfbd efbf bd09  ......H.6.......
003d5520: efbf bdef bfbd efbf bd4e efbf bdef bfbd  .........N......
003d5530: efbf bdef bfbd 58ef bfbd efbf bd2e efbf  ......X.........
003d5540: bdde 83ef bfbd 591a efbf bd63 42ef bfbd  ......Y....cB...
003d5550: efbf bddf a733 efbf bd13 66ef bfbd 1aef  .....3....f.....
003d5560: bfbd 44ef bfbd efbf bd35 efbf bd66 6aef  ..D......5...fj.
003d5570: bfbd 0853 efbf bdef bfbd 17ef bfbd 5371  ...S..........Sq
003d5580: 5d4b 5cef bfbd efbf bdef bfbd 47ef bfbd  ]K\.........G...
003d5590: 4bef bfbd 28ef bfbd 1b0a 0a              K...(......

Может ли кто-нибудь более опытный прокомментировать это? Большое спасибо!

0 голосов
/ 01 ноября 2019

Проблема, вероятно, в том, что println предназначен для текста, и этот текст кодируется как Unicode, который использует несколько байтов для некоторых или всех символов, в зависимости от того, какая версия Unicode.

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

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

...