2012-04-02 2 views
2

문자열로 조금 처리해야하는 erlang 모듈을 작성하고 있지만, 일부 tcp recv를 수행 한 다음 데이터를 구문 분석합니다.기본적으로 Erlang 바이너리 문자열

데이터를 일치시키고 문자열을 조작하는 동안 나는 항상 binary:split(Data,<<":">>)과 같은 이진 모듈을 사용하며 기본적으로 항상 <<"StringLiteral">>을 사용합니다.

까지 지금까지 나는 (목록을 사용하여) 대체 방법에서 어려움이나 누락 된 메소드를 발견하지 못했고 모든 것이 어쩌면 < <을 추가하는 것을 제외하고는 아주 자연스럽게 나오고 있지만 문자열을 처리하는 방법이 내가 알지 못하는 결점이있다.

힌트가 있습니까?

답변

4

문자열이 바이너리에서 인코딩되는 방식을 잘 알고 있어야합니다. 코드에서 < < "StringLiteral">>을 수행 할 때 코드 포인트 목록의 이진 직렬화라는 사실을 알고 있어야합니다. Erlang 컴파일러는 코드를 ISO-8859-1 문자로 읽습니다. 따라서 Latin-1 문자 만 사용하고 일관성있게 작성한다면 괜찮을 것입니다. 그러나 이것은 국제화에 그리 친숙하지 않습니다.

오늘날 대부분의 응용 프로그램 소프트웨어는 유니 코드 인코딩을 선호합니다. UTF-8은 첫 번째 128 코드 포인트에 대해서는 < < "StringLiteral">>과 호환되지만 두 번째 코드 포인트에는 해당하지 않으므로주의하십시오. 코드에 < < "StrïngLïteral">>을 사용하면 UTF-8로 인코딩 된 웹 응용 프로그램에 표시되는 내용에 놀랄 것입니다.

< < "StrïngLterteral"/ utf8 >>의 형태로 바이너리 지원을위한 EEP 제안이 있었지만 이것이 마무리 된 것으로 생각하지 않습니다.

스플릿 할 IS0-8859-1 바이트가 포함 된 멀티 바이트 문자가 있으면 binary : split/2 함수가 예기치 않은 결과를 UTF-8로 가질 수 있습니다.

UTF-16은 더 효율적으로 구문 분석 될 수 있고 32 비트 문자가 없다고 가정하거나 가정 할 경우 인덱스로 쉽게 분할 될 수 있기 때문에 UTF-16을 사용하는 것이 더 좋은 인코딩이라고 주장합니다.

unicode module은 사용해야하지만 리터럴을 사용할 때는주의해야합니다.

3

유일한주의 사항은 바이너리가 바이트 조각이지만 목록은 유니 코드 코드 포인트 목록입니다. 다시 말하면, 후자는 자연스럽게 유니 코드입니다. 전자는 보통 UTF-8과 같은 일종의 인코딩을 요구합니다.

내 지식으로는 귀하의 방법에는 단점이 없습니다.

5

귀하와 귀하의 팀원이 귀하의 문자열이 목록이 아닌 바이너리라는 것을 기억하고 있다면이 접근 방식에 고유 한 문제는 없습니다. 사실, Couch DB는 이러한 접근 방식을 좋은 배당금을 지불 한 최적화 도구로 사용했습니다.

2

바이너리는 문자열을 저장하는 데 매우 효율적인 구조입니다. 64B보다 긴 경우 프로세스 힙 외부에도 저장되므로 GC의 대상이 아닙니다 (마지막으로 참조가 손실되었을 때 다시 계산하여 GC'ed). 성능 문제가 발생할 때 복사를 피하기 위해 iolists를 연결하는 것을 잊지 마십시오.

관련 문제