Monday, January 27, 2014

BinaryWriter로 String을 썼는데 앞에 쓰레기값이 붙음 어떻게 해야 함?

그거 문자열 길이임 ㅋㅋㅋ

System.IO.BinaryWriter(System.IO.Stream)
"제공된 스트림을 기반으로 UTF-8을 문자열의 인코딩으로 사용하여 BinaryWriter 클래스의 새 인스턴스를 초기화합니다."

void BinaryWriter.Write(string)
"BinaryWriter의 현재 인코딩으로 된 이 스트림에 문자열의 길이가 맨 앞에 나오는 문자열을 쓴 다음 사용된 인코딩과 스트림에 쓰여지는 특정 문자의 길이만큼 스트림의 현재 위치를 앞으로 이동합니다"

그럼 이렇게 쓴 문자열을 읽을 때는 어떻게 해야 할까?
일단 integer를 하나 읽고, 거기서... 그럴 리가 없고

그냥 읽으면 된다.
BinaryReader.ReadString()은 문자열의 길이가 맨 앞에 오는 문자열을 읽게 되어 있다.

VS2010의 이 함수 설명은 해석이 괴상한데, 사실 원문도 좀 이상하긴 하다.

현재 스트림에서 문자열을 읽습니다. 한 번에 7비트 정수로 인코딩된 문자열 길이는 해당 문자열 앞에 옵니다.

원문은 이거다:
Reads a string from the current stream. The string is prefixed with the length, encoded as an integer seven bits at a time.
String이 length로 prefixed되어 있다는 중요한 사실을 먼저 말하는 게 당연하다.

위 번역은 일단 쉼표(,)로 구분된 문장을 잘못 번역했다.
(그) 문자열은 (문자열) 길이가 (맨) 앞에 오며, 이것(문자열 길이를 나타내는 정수)은 한 번에 7비트 정수로 인코딩되어 있습니다.

한 번에 7비트 정수로 인코딩(encoded as an integer seven bits at a time)은 도대체 무슨 소리일까?
같은 궁금증을 가진 사람이 역시 있었다:
답변자는 BinaryReader의 소스코드까지 따라가 보았다. 존경한다.
요약하면, 문자열 길이는 int의 배열로 저장되는 게 아니라, 8비트(=1바이트) 중 최상위 1비트를 다음 바이트가 필요한 지 여부를 나타내는 데 씀으로써 정수 크기에 따라 필요한 바이트 수에 맞게 알아서 잘(...) 쓴다는 것이다.
예를 들어 127까지는 7비트 이내니까 그냥 쓰고, 그보다 큰 숫자는 앞에 표시해서(아마도 0이 아니라 1로 세팅하거나 그런 거겠지) 다음 바이트도 (문자열이 아니라 문자열 길이를 나타내는) 정수로 읽게 하는 것이다. - 대충 이해한 거라 틀릴 수도 있지만 대략의 내용은 맞을 것이다.

그냥 7bitEncoding을 이용해 인코딩되어 있다(encoded by 7bitEncoding)라고 했으면 7bitEncoding이라는 게 있나 보다 하고 넘어갔을 텐데 encoded as an integer seven bits at a time이라는 문장이 오해를 불렀다.
전문 용어를 전문 용어가 아닌 척하고 쓰는 건 나쁜 글쓰기 습관이다. 특히나 개념에 대한 검색을 어렵게 한다는 점에서 그렇다. Encode ... ~ bits at a time이 업계의 관용구인가 알아보려고 해도 알 수가 없잖아?

No comments:

Post a Comment

창 핸들을 만드는 동안 오류가 발생했습니다

System.ComponentModel.Win32Exception was unhandled   MyForm w = new MyForm IntPtr handle = wnd.Handle;   // Exception occurs here class MyFo...