2017-02-22 52 views
-3

Итак, у меня есть строка из тысяч 1 и 0, которую я хочу сохранить в файл как двоичный (так что размер файла невелик). К сожалению, я не могу понять, как это сделать, не запуская NumberFormatExceptions.Преобразование строки из 1 и 0 в двоичный файл

Я пробовал Byte.parseByte, но это не работает. Любая помощь будет принята с благодарностью.

try { 
     File file = new File(BINARY_FILE); 
     DataOutputStream dso = new DataOutputStream(new FileOutputStream(file)); 
     for (int j = 0; j < bits.length(); j += 8) { 
      Byte b = Byte.parseByte(bits.substring(j, j + 8)); 
      dso.write(b); 
     } 
    } catch (IOException e) { 
     System.out.println("Error"); 
    } 
+0

показать код, который вы пробовали –

+0

Добавлено: переменная бит - это строка из 1 и 0. – BananaPineapple

+0

Кроме того, гарантируем ли мы, что длина строки будет делиться на 8? –

ответ

2

Если все, что вам нужно сделать, это написать байт, не обернуть DataOutputStream.

Вы должны также использовать try-with-resources, чтобы закрыть поток файлов по завершении.

При анализе 8 бит вам нужно указать radix 2, иначе вы будете разбирать номера базы-10, а не бинарные.

Разбор предназначен для подписанных номеров, поэтому, поскольку вы используете 8-битный беззнаковый байт, вы должны разобрать int, а не byte.

Вы не должны использовать valueOf(), но вместо этого используйте parseInt(). Нет необходимости получать объект в штучной упаковке.

Таким образом, вы код должен быть:

try { 
    File file = new File(BINARY_FILE); 
    try (FileOutputStream out = new FileOutputStream(file)) { 
     for (int j = 0; j < bits.length(); j += 8) { 
      int b = Integer.parseInt(bits.substring(j, j + 8), 2); 
      out.write(b); 
     } 
    } 
} catch (IOException e) { 
    System.out.println("Error"); 
} 

parseByte(s, 2) является знаковым синтаксическим анализом, так что onlu поддерживает значения между "-10000000" (-128) и "01111111" (127). Любой 8-значный двоичный номер, начинающийся с 1, потерпит неудачу с java.lang.NumberFormatException: Value out of range. Value:"11111111" Radix:2

+0

Кажется, неэффективно использовать 32-битный int, когда 8-битовый байт будет делать, хотя, из-за знака. –

+0

@DM ['write()'] (https://docs.oracle.com/javase/8/docs/api/java/io/FileOutputStream.html#write-int-) принимает параметр 'int' как параметр , хотя он использует только 8 младших бит, поэтому он будет преобразован в 'int' в любом случае, независимо от того, будете ли вы разбираться с' byte', 'short' или' int'. Невозможно разобрать байты без ошибок, поэтому также можно проанализировать 'int', так как это то, что хочет этот метод. – Andreas

+0

Это казалось работой, но будет продолжать пытаться улучшаться, если есть что-то лучше. – BananaPineapple

1

Я хотел бы обратиться к одной вещи, которая еще не была: как обрабатывать нечетные биты.

Вы не можете записать отдельные биты в файл, только байты. Размеры файлов всегда полные байты, и даже если Java может обрабатывать файлы с размером файла в долях байта, ваша файловая система не сможет.

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

for (int j = 0; j < bits.length(); j += 8) { 
     int b; 
     if (j + 8 < bits.length()) 
     { 
      b = Integer.parseInt(bits.substring(j, j + 8), 2); 
     } 
     else 
     { 
      b = Integer.parseInt(bits.substring(j), 2); 
     } 
     dso.write(b); 
    } 

Теперь ваш substring не будет идти от конца строки.

Что касается того, как различать строку, заканчивающуюся на «00001111», и строку, заканчивающуюся на «1111» (которая имеет одно и то же значение байта), возможно, вы могли бы написать в начале файла байт с значение bits.length % 8. Это позволит вам узнать, как обращаться с этим последним байтом. Если это, например, 6, то вы знаете, что 1111 действительно «001111», а не «1111». Если это 4, то это действительно было «1111».

 Смежные вопросы

  • Нет связанных вопросов^_^