방법은 :
String input = ... // my UTF-16 string
StringBuilder sb = new StringBuilder(input.length());
for (int i = 0; i < input.length(); i++) {
char ch = input.charAt(i);
if (ch <= 0xFF) {
sb.append(ch);
}
}
byte[] ascii = sb.toString().getBytes("ISO-8859-1"); // aka LATIN-1
이것은 아마도 우리가 두 번 문자를 복사하기 때문에 큰 문자열이 변환을 수행하는 가장 효율적인 방법은 아니다. 그러나, 그것은 간단하다는 장점이 있습니다.
실제로 엄밀히 말하자면 8 비트 ASCII와 같은 문자 집합이 없습니다. ASCII는 7 비트 문자 세트입니다. LATIN-1은 "8 비트 ASCII"문자 세트 (그리고 유니 코드의 블록 0은 LATIN-1과 동일합니다)에 가장 가까운 것입니다. 그래서 나는 그것이 당신이 의미하는 것이라고 가정 할 것입니다.
편집 : 질문에 대한 업데이트에 비추어,이 솔루션은 더 간단하다 :
String input = ... // my UTF-16 string
byte[] ascii = new byte[input.length()];
for (int i = 0; i < input.length(); i++) {
ascii[i] = (byte) input.charAt(i);
}
이 솔루션은보다 효율적입니다. 바이트 수를 예상 할 수 있기 때문에 중간 버퍼로 StringBuilder를 사용하지 않고 바이트 배열을 미리 할당하고 (잘린) 문자를 복사 할 수 있습니다.
그러나이 방법으로 잘못된 데이터를 처리하는 것이 현명하다고 나는 확신하지 못합니다.
EDIT 2 : 여기에 하나 더 애매한 "잡았다"가 있습니다. 유니 코드는 실제로 코드 포인트 (문자)가 "대략 21 비트"값 ... 0x000000에서 0x10FFFF ...로 정의되며 대리모를 사용하여> 0x00FFFF 코드를 나타냅니다. 즉, 유니 코드 코드 포인트> 0x00FFFF는 실제로 UTF-16으로 두 개의 "문자"로 표현됩니다. 내 대답이나 다른 사람들도이 (솔직히 비판적 인) 요점을 고려하지 않습니다. 실제로 Java에서 코드 포인트> 0x00FFFF를 다루는 것은 일반적으로 다소 까다 롭습니다. 이것은 'char'가 16 비트 유형이고 String이 'char'로 정의된다는 사실에서 유래합니다.
편집 3 :
String input = ... // my UTF-16 string
byte[] ascii = new byte[input.length()];
for (int i = 0; i < input.length(); i++) {
char ch = input.charAt(i);
ascii[i] = (ch <= 0xFF) ? (byte) ch : (byte) '?';
}
이
"away away"??? 당신은 "버림받은"것을 의미합니까? 버려 졌니? –
처음부터 명확하지 않은 것에 대해 유감스럽게 생각합니다. 사실, 나 자신이 너무 분명하지 않다. 내가 읽은 책의 연습에서는 "0xFF를 초과하는 코드는 단순히 바이트로 캐스팅되어 어쨌든 추가됩니다 (잘못된 데이터를 자동으로 추가해야 함)." – His
0xFF는 ASCII 문자에 대해 유효한 값이 아닙니다. ASCII는 7 비트이므로 가장 높은 유효한 값은 0x7F입니다. –