2011-12-16 2 views
1

В основном я пытаюсь использовать BufferedWriter для записи в файл с помощью Java. Проблема в том, что я на самом деле делаю некоторое сжатие, поэтому я генерирую ints от 0 до 255, и я хочу написать символ, значение ASCII которого равно этому int. Когда я пытаюсь записать файл, он записывает много символов ?, поэтому, когда я читаю файл, он читает их как 63, что явно не то, что я хочу. Любые идеи, как я могу это исправить?Как вы пишете любой символ ASCII в файл на Java?

Пример кода:

int a = generateCode(character); //a now has an int between 0 and 255 
bw.write((char) a); 

всегда находится между 0 и 255, но иногда пишет '?'

+0

Можем ли мы увидеть код? – Tim

+0

добавил код к нему – Rohan

+0

Как насчет использования кодировки Base64? –

ответ

3

Вы действительно пытаетесь написать/прочитать байты в/из файла. Когда вы обрабатываете байт-ориентированные данные (в отличие от символьно-ориентированных данных), вы должны использовать классы InputStream и OutputStream, а не классы Reader и Writer.

В этом случае, вы должны использовать FileInputStream/FileOutputStream и завернуть с BufferedInputStream/BufferedOutputStream если вы делаете байты-на-время читает и пишет.

Эти надоедливые '?' символы возникают из-за проблем с процессом кодирования/декодирования, который происходит, когда Java преобразует символы и стандартную текстовую кодировку для вашей платформы. Преобразование из байтов в символы и обратно часто «потеряно» ... в зависимости от используемой схемы кодирования. Вы можете избежать этого, используя классы, ориентированные на байты.


(И ответы, которые указывают на то, что ASCII является 7-битный набор не 8-битный символ являются 100% правильно. Вы действительно пытаются чтения/записи двоичных октета, а не символы.)

+0

Да, вы, вероятно, используете BufferedWriter (следовательно, «bw») и BufferedReader, которые выполняют интерпретации символов. Вы должны использовать FileOutputStream/FileInputStream, которые немного сложнее использовать (только как раз), но вы получите нужный результат. –

+0

@jowierun - на самом деле кодировка происходит в другой части стека. Классы «BufferedReader» и «BufferedWriter» переносят экземпляры «Reader» и «Writer» соответственно. –

+0

он все еще не объясняет, как OP получает разные значения при чтении файла, если только он не пишет в одном виде и не читает в другом. что было бы довольно непоследовательно, если не сказать больше ... – soulcheck

1

Вам нужно решить, что вы на самом деле делаете. Вы пытаетесь написать файл байтов в файл, или вы пытаетесь написать закодированный текст? Потому что это разные концепции на Java; байтовый ввод-вывод обрабатывается подклассами InputStream и OutputStream, в то время как ввод символов ввода-вывода обрабатывается подклассами Reader и Writer. Если то, что вы действительно хотите записать, это байты в файл (который я угадываю из вашего упоминания о сжатии), используйте OutputStream, а не Writer.

Тогда есть еще одна путаница, о чем свидетельствует ваше упоминание о «символах ASCII от 0 до 255». Нет символов ASCII выше 127. Прочтите 15 минут, чтобы прочитать следующее: "The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!)" (by Joel Spolsky). Обратите особое внимание на части, где он объясняет разницу между набором символов и кодировкой, потому что это важно для понимания Java I/O. (Чтобы проверить, поняли ли вы, вот что вам нужно изучить: Java Writers - это классы, которые переводят вывод символов в байтовый вывод, применяя кодировку, указанную клиентом, к тексту и отправляя байты в OutputStream.)

1

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

Следующий пример кода записывает и считывает данные непосредственно в виде байтов, что означает 8-битные номера, которые имеют связанное с ними значение ASCII.

import java.io.*; 
public class RWBytes{ 
    public static void main(String[] args)throws IOException{ 
     String filename = "MiTestFile.txt"; 
     byte[] bArray1 =new byte[5]; 
     byte[] bArray2 =new byte[5]; 
     bArray1[0]=65;//A 
     bArray1[1]=66;//B 
     bArray1[2]=67;//C 
     bArray1[3]=68;//D 
     bArray1[4]=69;//E 
     FileOutputStream fos = new FileOutputStream(filename); 
     fos.write(bArray1); 
     fos.close(); 
     FileInputStream fis = new FileInputStream(filename); 
     fis.read(bArray2); 
     ByteArrayInputStream bais = new ByteArrayInputStream(bArray2); 
     for(int i =0; i< bArray2.length ; i++){ 
      System.out.println("As the bytem value: "+ bArray2[i]);//as the numeric byte value 
      System.out.println("Converted as char to printiong to the screen: "+ String.valueOf((char)bArray2[i])); 
     } 
    } 
} 

Фиксированное подмножество 7 битного кода ASCII является печати, А = 65, например, 10 соответствует «новой линии» характера, которые шаги вниз на одну строку на экране, когда найдена и «напечатаны». Существует множество других кодов, которые манипулируют экраном, ориентированным на символы, они невидимы и управляются представлением экрана, таким как вкладки, пробелы и т. Д. Существуют также другие управляющие символы, предназначенные, например, для вызова колокола.

Высший 8-разрядный конец выше 127 определяется как любой желающий, но только нижняя половина имеет стандартные значения.

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

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