문자열을 UTF-8로 인코딩


190

"ñ"문자가있는 문자열이 있는데 문제가 있습니다. 이 문자열을 UTF-8 인코딩으로 인코딩해야합니다. 이 방법으로 시도했지만 작동하지 않습니다.

byte ptext[] = myString.getBytes();
String value = new String(ptext, "UTF-8");

해당 문자열을 utf-8로 어떻게 인코딩합니까?


2
정확히 무엇을하려고하는지 명확하지 않습니다. myString에 ñ 문자가 올바르게 포함되어 있고이를 바이트 배열로 변환하는 데 문제가 있거나 (이 경우 Peter 및 Amir의 답변 참조) myString이 손상되어 문제를 해결하려고합니다 (이 경우 Joachim의 답변 참조) 그리고 나)?
Michael Borgwardt

utf-8 인코딩을 사용하여 myString을 서버로 보내야하며 "ñ"문자를 utf-8 인코딩으로 변환해야합니다.
Alex

1
글쎄, 그 서버가 UTF-8을 기대한다면, 당신이 그것을 보내야하는 것은 문자열이 아닌 바이트입니다. Peter의 답변에 따라 첫 번째 줄에 인코딩을 지정하고 두 번째 줄을 삭제하십시오.
Michael Borgwardt

@ 마이클 : 나는 진짜 의도가 무엇인지 명확하지 않다는 것에 동의합니다. 사람들이 문자열과 바이트간에 명시 적으로 변환 {In,Out}putStream{Read,Writ}ers하지 않고 명시 적으로 변환하려고하는 많은 질문이있는 것 같습니다 . 왜 궁금해?
tchrist

1
@Michael : 감사합니다. 그러나 그것은 또한 필요 이상으로 어렵게 만듭니다. 나는 그런 식으로 작동하는 언어를 좋아하지 않으므로 그 언어로 작업하지 마십시오. 바이트 대신 Java의 문자열 문자열 모델이 훨씬 더 쉽다고 생각합니다. Perl과 Python은 또한“모든 것이 유니 코드 문자열”모델을 공유합니다. 그렇습니다. 세 가지 모두에서 작업하면 여전히 바이트를 얻을 수 있지만 실제로 실제로 필요한 것은 거의 없습니다. 또한 내가 무슨 뜻인지 알면 고양이에게 잘못된 방향을 칫솔질하는 것과 같은 느낌이 든다. :)
tchrist

답변:


140

String Java의 객체는 수정할 수없는 UTF-16 인코딩을 사용합니다.

다른 인코딩을 가질 수있는 유일한 것은입니다 byte[]. 따라서 UTF-8 데이터가 필요한 경우가 필요합니다 byte[]. String예상치 못한 데이터가 포함 된 파일 이있는 경우 일부 바이너리 데이터를 잘못 변환 한 이전 위치에 문제가있는 것입니다 String(즉, 잘못된 인코딩을 사용하고 있음).


92
기술적으로 말하자면 byte []에는 인코딩이 없습니다. 바이트 배열 PLUS 인코딩은 문자열을 줄 수 있습니다.
피터 Štibraný

1
@ 피터 : 맞습니다. 그러나 인코딩을 첨부하는 byte[]것은 의미가 있습니다 String. 인코딩이 UTF-16이 아닌 경우에는 의미가 없지만 여전히 불필요한 정보는 아닙니다.
Joachim Sauer

4
String objects in Java use the UTF-16 encoding that can't be modified. 이 견적의 공식 소스가 있습니까?
Ahmad Hajjar

@AhmadHajjar docs.oracle.com/javase/10/docs/api/java/lang/… : "Java 플랫폼은 char 배열과 String 및 StringBuffer 클래스에서 UTF-16 표현을 사용합니다."
Maxi Gis

173

사용은 어떻습니까

ByteBuffer byteBuffer = StandardCharsets.UTF_8.encode(myString)

Peter와의 토론을보십시오. 그러나 질문에 대한 그의 가정이 옳다면 ByteBuffer를 반환하므로 솔루션이 여전히 아이디어가 아닙니다.
Michael Borgwardt

8
그러나 인코딩 된 문자열을 어떻게 얻습니까? 그것은 ByteBuffer를 반환합니다
Alex

7
@ 알렉스 : 그것은 가능하지 UTF-8로 인코딩 된 자바 문자열을 가지고. 바이트를 원하기 때문에 ByteBuffer를 직접 사용하거나 (네트워크 컬렉션을 통해 전송하는 것이 목표 일 경우 최상의 솔루션 일 수도 있음) array ()를 호출하여 바이트를 얻습니다 []
Michael Borgwardt

2
도움이 될만한 다른 것은 UnsupportedEncodingException을 던질 수있는 문자열 대신 Guava의 Charsets.UTF_8 열거 형을 사용하는 것입니다. 문자열-> 바이트 : myString.getBytes(Charsets.UTF_8)및 바이트-> 문자열 : new String(myByteArray, Charsets.UTF_8).
laughing_man

24
더 나은을 사용하십시오 StandardCharsets.UTF_8. Java 1.7 이상에서 사용 가능합니다.
Kat

81

Java7에서는 다음을 사용할 수 있습니다.

import static java.nio.charset.StandardCharsets.*;

byte[] ptext = myString.getBytes(ISO_8859_1); 
String value = new String(ptext, UTF_8); 

이것은 getBytes(String)선언하지 않는 것보다 장점이 있습니다 throws UnsupportedEncodingException.

이전 Java 버전을 사용하는 경우 문자 세트 상수를 직접 선언 할 수 있습니다.

import java.nio.charset.Charset;

public class StandardCharsets {
    public static final Charset ISO_8859_1 = Charset.forName("ISO-8859-1");
    public static final Charset UTF_8 = Charset.forName("UTF-8");
    //....
}

2
이것이 정답입니다. 누군가 문자열 데이터 유형을 사용하려는 경우 올바른 형식으로 사용할 수 있습니다. 나머지 답변은 바이트 형식 유형을 가리 킵니다.
Neeraj Shukla

6에서 작동합니다. 감사합니다.
Itsik Mauyhas

나에게도 정답. 한 가지, 위와 같이 사용하면 독일어 문자가?로 변경되었습니다. 그래서 나는 이것을 사용했다 : byte [] ptext = myString.getBytes (UTF_8); 문자열 값 = 새 문자열 (ptext, UTF_8); 이것은 잘 작동했습니다.
Farhan Hafeez

3
코드 샘플이 이해가되지 않습니다. 만약 ISO-8859-1로 먼저 변환, 바이트의 배열은 그 되지 다음 줄은 완전히 잘못된 것입니다 때문에, UTF-8. 물론 ASCII 문자열에서도 작동하지만 간단한 사본을 만들 수도 String value = new String(myString);있습니다.
Alexis Wilke

76

byte[] ptext = String.getBytes("UTF-8");대신에 사용하십시오 getBytes(). getBytes()UTF-8이 아닌 소위 "기본 인코딩"을 사용합니다.


9
@ 마이클 : 그는 분명히 문자열에서 바이트를 얻는 데 어려움을 겪고 있습니다. getBytes (encoding)가 어떻게 포인트를 놓치고 있습니까? 나는 그가 다시 변환 할 수 있는지 확인하기 위해 두 번째 줄이 있다고 생각합니다.
피터 Štibraný

1
나는 문자열이 깨진 것으로 해석하고 바이트로 변환하고 다시 (일반적인 오해) 변환하여 "수정"하려고합니다. 두 번째 줄이 결과를 확인하고 있다는 실제 표시는 없습니다.
Michael Borgwardt

@ 마이클, 없습니다, 그것은 단지 내 해석 일뿐입니다. 당신은 단순히 다릅니다.
피터 Štibraný

1
@ 피터 : 당신이 맞아, 우리는 Alex가 정말로 의미하는 바를 명확히해야합니다. 대답은 ... 편집하지 않는 한 비록 downvote을 철회 할 수 없습니다
마이클 Borgwardt

33

Java 문자열은 내부적으로 항상 UTF-16으로 인코딩되지만 실제로 다음과 같이 생각해야합니다. 인코딩은 문자열과 바이트 사이를 변환하는 방법입니다.

따라서 인코딩 문제가있는 경우 String을 사용할 때까지 해결하기에는 너무 늦습니다. 파일, DB 또는 네트워크 연결에서 해당 문자열을 생성하는 장소를 수정해야합니다.


1
문자열이 내부적으로 UTF-16으로 인코딩된다고 믿는 것은 일반적인 실수입니다. 일반적으로,하지만, String 클래스의 구현 고유의 상세 일뿐입니다. 문자 데이터의 내부 저장소는 공개 API를 통해 액세스 할 수 없으므로 특정 문자열 구현은 다른 인코딩을 사용하기로 결정할 수 있습니다.
jarnbjo

4
@jarnbjo : API는 명시 적으로 "문자열은 UTF-16 형식의 문자열을 나타냅니다"라고 명시합니다. 내부 형식으로 다른 것을 사용하는 것은 비효율적이며, 내가 알고있는 모든 실제 구현은 내부에서 UTF-16을 사용합니다. 따라서 당신이하지 않는 것을 인용 할 수 없다면, 당신은 꽤 터무니없는 헤어 스 플리 팅에 종사하고 있습니다.
Michael Borgwardt

데이터 구조의 공개 액세스와 내부 표현을 구분하는 것이 부적절합니까?
jarnbjo

6
JVM은 VM과 전혀 관련이없는 한 클래스 파일에서 문자열 인코딩에 UTF-8을 사용합니다. java.lang.String의 구현은 JVM에서 분리되어 있으며 내부 표현을 위해 다른 인코딩을 사용하여 클래스를 쉽게 구현할 수 있습니다. 실제로 대답이 잘못되었다는 것을 알아야합니다. 내부 형식으로 UTF-16을 사용하는 것은 대부분의 경우 메모리 소비와 관련하여 매우 비효율적이며 임베디드 하드웨어에 대한 Java 구현이 성능 대신 메모리에 대해 최적화되지 않는 이유를 알 수 없습니다.
jarnbjo

1
@jarnbjo : 그리고 한 번 더 : 표준 API 구현 UTF-16 이외의 것을 사용하여 문자열을 구현 하는 JVM의 구체적인 예를 제공 할 수 없다면 내 진술이 정확합니다. 그리고 아니요, String 클래스는 intern () 및 상수 풀과 같은 이유로 실제로 JVM에서 분리되지 않습니다.
Michael Borgwardt

22

이 방법으로 시도 할 수 있습니다.

byte ptext[] = myString.getBytes("ISO-8859-1"); 
String value = new String(ptext, "UTF-8"); 

1
나는 미쳐 가고 있었다. 먼저 "ISO-8859-1"의 바이트를 구해 주셔서 감사합니다.
Gian Gomen

2
이것은 잘못이다. 문자열에 유니 코드 문자가 포함되어 있으면 8859-1로 변환하면 예외가 발생하거나 잘못된 문자열이 잘못됩니다 (코드 포인트가 0x100 이상인 문자가없는 문자열 일 수 있음).
Alexis Wilke 3

12

잠시 후이 문제를 겪고 다음과 같은 방법으로 문제를 해결할 수있었습니다.

먼저 가져와야합니다

import java.nio.charset.Charset;

그런 다음 사용할 상수를 선언 UTF-8하고ISO-8859-1

private static final Charset UTF_8 = Charset.forName("UTF-8");
private static final Charset ISO = Charset.forName("ISO-8859-1");

그런 다음 다음과 같은 방식으로 사용할 수 있습니다.

String textwithaccent="Thís ís a text with accent";
String textwithletter="Ñandú";

text1 = new String(textwithaccent.getBytes(ISO), UTF_8);
text2 = new String(textwithletter.getBytes(ISO),UTF_8);

1
완벽한 솔루션.
Tunde Pizzle

9
String value = new String(myString.getBytes("UTF-8"));

"ISO-8859-1"로 인코딩 된 텍스트 파일을 읽으려면 다음을 수행하십시오.

String line;
String f = "C:\\MyPath\\MyFile.txt";
try {
    BufferedReader br = Files.newBufferedReader(Paths.get(f), Charset.forName("ISO-8859-1"));
    while ((line = br.readLine()) != null) {
        System.out.println(new String(line.getBytes("UTF-8")));
    }
} catch (IOException ex) {
    //...
}

2

인코딩 형식을 지정하여 특수 문자를 인코딩하기 위해 아래 코드를 사용했습니다.

String text = "This is an example é";
byte[] byteText = text.getBytes(Charset.forName("UTF-8"));
//To get original string from byte.
String originalString= new String(byteText , "UTF-8");

2

NetBeans 기본 인코딩 UTF-8을 구성하는 방법을 단계별로 안내합니다. 결과적으로 NetBeans는 모든 새 파일을 UTF-8 인코딩으로 작성합니다.

NetBeans 기본 인코딩 UTF-8 단계별 가이드

  • NetBeans 설치 디렉토리의 etc 폴더로 이동

  • netbeans.conf 파일 편집

  • netbeans_default_options 줄 찾기

  • 해당 행 안에 인용 부호 안에 -J-Dfile.encoding = UTF-8을 추가하십시오.

    (예 : netbeans_default_options="-J-Dfile.encoding=UTF-8")

  • NetBeans 재시작

NetBeans 기본 인코딩 UTF-8을 설정합니다.

netbeans_default_options는 따옴표 안에 추가 매개 변수를 포함 할 수 있습니다. 이러한 경우 문자열 끝에 -J-Dfile.encoding = UTF-8을 추가하십시오. 다른 매개 변수와 공백으로 분리하십시오.

예:

netbeans_default_options = "-J-client -J-Xss128m -J-Xms256m -J-XX : PermSize = 32m -J-Dapple.laf.useScreenMenuBar = true -J-Dapple.awt.graphics.UseQuartz = true -J-Dsun. java2d.noddraw = true -J-Dsun.java2d.dpiaware = true -J-Dsun.zip.disableMemoryMapping = true -J-Dfile.encoding = UTF-8 "

자세한 내용 은 여기 링크


0

이것은 내 문제를 해결했다

    String inputText = "some text with escaped chars"
    InputStream is = new ByteArrayInputStream(inputText.getBytes("UTF-8"));
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.