문자셋 이름이 상수가 아닌 이유는 무엇입니까?


211

문자셋 문제는 그 자체로 혼란스럽고 복잡하지만 그 위에 문자셋의 정확한 이름을 기억해야합니다. 그렇 "utf8"습니까? 아니면 "utf-8"? 아니면 "UTF-8"? 인터넷에서 코드 샘플을 검색하면 위의 모든 내용이 표시됩니다. 상수로 명명하고 사용하는 것이 Charset.UTF8어떻습니까?


19
+1 : 이것은 또한 항상 나를 괴롭 혔습니다. 그런데 같은 이야기가 계속됩니다 MessageDigest#getInstance().
BalusC 2009

2
실제 답변을 얻으려면 Sun 직원에게 문의해야합니다. 행운을 빌어 그 :-)
스티븐 C

1
Stephen C : 공개 메일 링리스트에서 논의 된 것 같습니다. -일요일에 누군가.
Tom Hawtin-tackline

답변:


160

질문에 대한 간단한 대답은 사용 가능한 문자 집합 문자열이 플랫폼마다 다릅니다.

그러나 6 개가 있어야하므로 오래 전부터 상수를 만들 수있었습니다. 왜 그들이 아닌지 모르겠습니다.

JDK 1.4는 Charset 타입을 소개함으로써 큰 ​​일을했습니다. 이 시점에서 그들은 더 이상 문자열 상수를 제공하고 싶지 않았습니다. 목표는 모든 사람이 Charset 인스턴스를 사용하도록하는 것이기 때문입니다. 그렇다면 6 가지 표준 Charset 상수를 제공하지 않는 이유는 무엇입니까? Martin Buchholz가 내 옆에 앉아 있었기 때문에 물었습니다. 그 당시에는 여전히 반 베이크 된 것 외에는 JDK API가 너무 적습니다. Charset을 받아들이고 Charset 과부하는 보통 약간 더 나빴습니다.

JDK 1.6에서만 Charset 과부하로 모든 것을 꾸미는 것은 슬픈 일입니다. 그리고 이것은 거꾸로 된 성능 상황이 여전히 존재한다는 것입니다 (이유는 믿을 수 없을 정도로 이상하고 설명 할 수 없지만 보안과 관련이 있습니다!).

간단히 말해서-자신의 상수를 정의하거나 Tony the Pony와 연결된 Guava의 Charsets 클래스를 사용하십시오 (라이브러리는 실제로 아직 릴리스되지는 않았지만).

업데이트 :StandardCharsets 클래스는 JDK 7에 있습니다.


궁금한 점이 있다면 구아바의 출시 (알파 / 베타 / 무엇)가 있을지 아십니까? 프로젝트 홈페이지는 이것에 약간의 영향을 미칩니다.
Jonik

나갈 때까지 칠면조가 없어요!
Kevin Bourrillion 2009

이유가 엄청나게 이상하고 설명 할 수 없지만 보안과 관련이있는 이유는 사용자 정의 문자 집합을 통해 수정 가능한 문자열을 만들 수는 있지만 문자열보다 실제로 더 빨리 작동 할 수 있었기 때문입니다 (실제로는 문자 집합을 찾습니다). String(byte bytes[], int offset, int length, Charset charset)구현 방법을 생략 / 방치합니다 . 실제로 큰 바이트 []에서 작은 문자열을 만들 때 성능 저하는 결코 그리 크지 않습니다.
bestsss

7
불공평합니다! 당신은 그러한 훌륭한 자원에 접근 할 수 있습니다. 한 번 말했다 곳 = (나는 다른 답변을보고 "내가 물었다 그래, 그래서 조쉬 [블로흐] 그것에 대해 ..."
kevinarpe

의 PrintStream는 문자 집합을 지원하지 않습니다
rofrol

102

2 년 후 Java 7의 StandardCharsets는 이제 6 개의 표준 Charset에 대한 상수를 정의합니다.

Java 5/6을 사용 하는 경우 Kevin Bourrillion 및 Jon Skeet이 제안한대로 Guava의 Charsets 상수를 사용할 수 있습니다 .


29

나는 우리가 그것보다 훨씬 더 잘 할 수 있다고 주장하고 싶습니다 ... 왜 보장 가능한 캐릭터 세트가 직접 액세스 할 수 없습니까? 문자열 이름이 아닌을 Charset.UTF8참조해야 Charset합니다. 그렇게하면 UnsupportedEncodingException모든 곳 을 다룰 필요가 없습니다 .

또한 .NET은 기본적으로 UTF-8을 기본값으로 설정하여 더 나은 전략을 선택했다고 생각합니다. 그것은 단순히 속성을 암호화하는 "운영 체제의 기본을"이름으로 망쳐 Encoding.Default- 어떤 없는 .NET 자체 내에서 기본이 :(

돌아 가기 자바의 캐릭터 세트 지원에 대한 불평에 - 이유를 생성자가없는 FileWriter/ FileReader소요 Charset? 기본적으로 그 때문에 그 제한에 거의 쓸모 클래스는 - 당신은 거의 항상 필요 InputStreamReader전세계 거의 FileInputStream또는 출력에 대한 동등 :(

간호사, 간호사-내 약 어 where 어?

편집 :이 질문에 실제로 대답하지 않은 것이 나에게 발생합니다. 진정한 대답은 아마도 "아무도 그것에 대해 생각하지 않았다"또는 "누군가가 나쁜 생각이라고 생각했다"라는 것입니다. 이름이나 문자셋을 제공하는 사내 유틸리티 클래스가 코드베이스의 중복을 피할 것을 강력히 제안합니다 ... 또는 이 답변을 처음 작성할 때 Google에서 사용한 클래스를 사용할 수 있습니다 . (Java 7부터는 StandardCharsets대신 사용 합니다.)


2
+1. 그러나 게으른 로딩을 허용하기 위해 필드가 아닌 방법으로 (알겠습니다, 아마도 UTF-8을 원할 것입니다. 불행히도 이것은 결정을 내리는 사람들에게 인기가없는 것 같습니다.
Tom Hawtin-tackline

나는 그 문자셋을 열심히로드하는 것이 큰 비용이되지 않기를 희망하지만 메소드에 충분히 만족할 것입니다.
Jon Skeet

1
우리는 열망하는 클래스 로딩을 중단하기 위해 십자군에 있습니다. / 방금 "UTF-8"에 대한 JDK를 검색했습니다. 165 개 파일에서 270 개의 일치 항목을 찾았습니다. 그것의 많은 것이 오래된 Apache 쓰레기에 있지만 (내 팀이 기여한 것으로 생각합니다)
Tom Hawtin-tackline

1
@ tackline : 열망하는 클래스 로딩이 시간이 지남에 따라 마운트되는 것들 중 하나라고 생각합니다. 여기에 몇 개의 수업이 있습니다. 여기에 몇 개의 수업이 있습니다-각각 개별적으로 무해한 소리가 들리면 큰 차이를 만들 수 있습니다.
Jon Skeet

구아바 문자셋에 대한 마지막 연결이 끊어졌습니다.
LarsH

28

자바 1.7

import java.nio.charset.StandardCharsets

전의: StandardCharsets.UTF_8 StandardCharsets.US_ASCII


5

인코딩 API의 현재 상태는 원하는 것으로 남습니다. 자바 6 API의 일부는 허용하지 않습니다 Charset(에 문자열 대신에 logging, dom.ls, PrintStream, 등이있을 수 있습니다). 인코딩이 표준 라이브러리의 다른 부분에 대해 다른 표준 이름을 갖는 것으로 도움이되지 않습니다.

나는 물건이 어디에 있는지 어떻게 이해할 수 있습니다. 그 문제를 해결하는 방법에 대한 훌륭한 아이디어가 있는지 확실하지 않습니다.


여담으로...

여기 에서 Sun의 Java 6 구현 이름을 찾을 수 있습니다 .

UTF-8의 경우, 정규 값은 "UTF-8"위해 java.nio"UTF8"위해 java.langjava.io. 스펙이 JRE를 지원하도록 요구하는 유일한 인코딩은 다음과 같습니다. US-ASCII; ISO-8859-1; UTF-8; UTF-16BE; UTF-16LE; UTF-16 .


2
클래스가 "바이트가 아닌 문자를 써야하는 상황에서 PrintWriter 클래스를 사용해야합니다."라고 명확하게 말하고 있기 때문에 PrintStream 클래스를 싫어하지는 않습니다. (모든 상황과 같습니다 ...)
Kevin Bourrillion

2

오래 전에 UTF_8, ISO_8859_1 및 US_ASCII Charset 상수를 사용하여 유틸리티 클래스를 정의했습니다.

또한, 몇 년 전에 오랜 시간 (2 년 이상)가 나는 사이의 간단한 성능 테스트했다 new String( byte[], Charset )new String( byte[], String charset_name )후자의 구현이 발견 훨씬 더 빨리. 소스 코드를 살펴보면 실제로 다른 경로를 따르는 것을 알 수 있습니다.

그런 이유로 나는 같은 클래스에 유틸리티를 포함시켰다

public static String stringFromByteArray (
    final byte[] array,
    final Charset charset
)
{
    try
    {
        return new String( array, charset.name( ) )
    }
    catch ( UnsupportedEncodingException ex )
    {
        // cannot happen
    }
}

왜 String (byte [], Charset) 생성자가 똑같이하지 않는가?


1
Charset예외가 발생할 수 있으므로 필요가 등록 할 수 없습니다. IIRC, JDK7에는 알려진 Charset구현을 더 빠르게하기 위해 약간의 변경이있었습니다 (추가 사본 제거).
Tom Hawtin-tackline
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.