2014-06-13 3 views
1

GameBoy 카트를 읽는 Arduino 프로그램을 작성했습니다. Java는 시작 문자를 보내고 바이트 읽기 및 보내기를 시작합니다. 16 진수 편집기 (또는 텍스트 편집기)에서 덤프 된 롬을 열면 언뜻보기에는 동일하지만 편집기에서 비교 기능을 사용하면 덤프 된 ROM의 모든 0x3F 문자가 올바르지 않다는 사실이 강조됩니다.내 Arduino 프로그램에있는 모든 기능은이 작업을 수행하기 전에 테스트를 마쳤으므로 내가 생각할 수있는 유일한 점은 자바 측을 테스트하는 것이 었습니다. 이것을 시험해보기 위해 간단히 10 진수 옆에 모든 아스키 문자 (0-255)를 연속으로 보내는 또 다른 간단한 Arduino 프로그램을 만들었습니다. 사실 6 개의 다른 표현이 있다는 것을 깨달았습니까?여섯 가지 '?' ASCII 문자?

다음
59: ; 
60: < 
61: = 
62: > 
63: ? < 
64: @ 
65: A 
66: B 
... 
125: } 
126: ~ 
127: 
128: € 
129: ? < 
130: ‚ 
131: ƒ 
132: „ 
... 
140: Π
141: ? < 
142: Ž 
143: ? < 
144: ? < 
145: ‘ 
146: ’ 
147: “ 
... 
154: š 
155: › 
156: œ 
157: ? < 
158: ž 
159: Ÿ 
160:   

문제의 자바 코드 : 문자, 여기에 파일의 그 부분입니다

final Arduino board = new Arduino("COM5", 115200); 
BufferedWriter rom = new BufferedWriter(new FileWriter("[ROM].gb")); 
board.write((byte)0); 
Thread.sleep(10000); 
while (board.hasavailable() > 0) { 
    String data = new String(board.read(board.hasavailable())); 
    rom.write(data); 
    Thread.sleep(1000); 
} 
rom.flush(); 
rom.close(); 

나는이 의사 소통에 문제가되는 볼 수없는 전송 속도가 잘못 경우가하는 것처럼 쓰레기가 될 것입니다, 이것이 ASCII 형식의 UTF-8 같은 텍스트 형식의 문제라면 분명히 똑같이 될 것입니다 ... 기본적으로 Java는 '?' 그리고 항상 첫 번째 인스턴스라고 가정합니다. 바이트 []를 문자열로 캐스팅 할 때 뭔가 빠졌는데, 이는 이것이 내가하는 것처럼 명백한 문제라고 생각하기 때문입니다.

편집 1 : 나는 모든 문자가 동일하게 얻을 수있는 referance에로 asciitable.com을 사용하고있다

.

byte[] data = board.read(readsize); 
for (byte in : data) 
    rom.write(in); 

확장 세트의 모든

은 (128+)이 될의 '?':

나는 또한 내가 여기에 코드를 작성 파일을 변경하면 것을 발견했다. 그것은 bufferedWriter에 문제가 될 수 있습니까?

편집 2 : 재현 예를 들어 여기에

은 내가 사용하고있는 아두 이노와 자바 코드입니다.

http://pastebin.com/Tijjdb0A

자바 쓴 후 파일이 16 진수 편집기에서이를 확인하고 위에서 언급 한 문자가 모두 0x3F입니다로 변경 한 것을 알 수 있습니다.

+0

어디에서 문자를 인쇄하고 있습니까? 어쩌면 그 장치는 그 문자들을 출력 할 수없고'? '를 디폴트 출력으로 사용할 수 있습니다. –

+1

또한 [여기] (http://www.asciitable.com/)는 ASCII 및 확장 ASCII 테이블입니다. –

+0

@SotiriosDelimanolis 결국 나는 그 바이트가 실제로 '?'의 다른 값 대신에 0x3F라고 말했 읍니다. 그리고 저는 그 페이지를 반복해서보고있었습니다. Java가 사실상 잘못된 문자를 가정합니다. –

답변

0

저는 문제는 여러분이 바이트에서 문자열로 원시 데이터를 변환하고 버퍼링 된 작성기에만 문자열을 쓰는 것이라고 생각합니다. 당신이 new String(byte[])를 호출 할 때, 워드 프로세서에 따라

Constructs a new String by decoding the specified array of bytes using the platform's default charset. 

이 그 다음, 그것은 디폴트의 캐릭터 세트는 컴퓨터에 무엇이든에 문자열입니다 가정, 당신의 바이트를 취 UTF-16으로 변환을 의미합니다 자바에서 문자열의 내부 표현입니다. 대부분의 플랫폼에서 "기본 문자 집합"은 UTF-8을 의미하며 UTF-8에서는 "확장 ASCII"의 대부분의 바이트 즉 128 이상은 더 긴 문자의 일부로 두 개 이상의 바이트를 차지합니다. 바이트가 유효한 UTF-8 문자열이 아니므로 일부 문자가 손상됩니다.

이 아닌 BufferedOutputStream(FileOutputStream)을 사용하여 문자열을 먼저 작성하는 대신 파일에 직접 바이트를 쓰는 것이 좋습니다. 모든 것이 정상적으로 처리됩니다.

+0

Ok ... 불필요하게 복잡해 보입니다. FileOutoutStream을 사용하고 작동합니다 (아직 버퍼링하지 않았습니다). 그것은 원시 바이트 목록을 받아들이 기 때문입니다. –

0

"모든 ASCII 문자 (0-255)": 최소한 ASCII가 무엇인지 이해하지 못합니다. 하지만 그렇게 할 필요는 없습니다. 그것은 쓸모가 없습니다. €, ..., Ÿ, ...은 ASCII가 아닙니다.

임의 바이트를 문자로 처리하려면 1 바이트 당 1 바이트를 처리해야합니다. 문자 집합은 256 자 이상이어야하며 0-255를 1 바이트 문자로 사용하는 인코딩이 필요합니다. CP437을 사용해보십시오. Java가 잘 처리합니다. OutputStreamWriter을보십시오.

0

제공되는 다른 답변에 만족스러워서 기쁩니다. 질문 제목에 의해 제기 된 오해를 해결하기 위해 :

6 개의 다른 '?' ASCII 문자?

아니요, 하나 이상의 물음표가 ASCII로 표시됩니다. ASCII는 0에서 127 사이의 값으로 만 문자를 할당하며 그 중 하나 (십진 63) 만 물음표입니다. 128에서 255까지의 위치에 문자를 할당하는 ASCII에 대한 많은 "확장"이 있지만, 심지어 일부 값은 할당 해제 될 수 있습니다.

출력물에 표시되는 5 개의 추가 물음표는 할당되지 않은 위치 인 Windows-1252에 해당합니다. Windows-1252는 Microsoft Windows의 북미 버전에서 설정된 기본 문자이므로 문자 세트를 지정하지 않고 Reader 또는 Writer 클래스 또는 String 생성자를 사용할 때 작동합니다.

Java가 바이트를 문자로 변환 할 때 (또는 그 반대로) "잘못된 입력 또는 맵핑이 불가능한 문자 시퀀스"가 발생하면 대체 문자로 물음표가 사용됩니다. 이것은 Charset Javadoc에서 암시되었지만 실제로는 잘 설명되어 있지 않습니다.