文字列を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

myStringをutf-8エンコーディングでサーバーに送信する必要があり、「ñ」文字をutf-8エンコーディングに変換する必要があります。
Alex

1
まあ、そのサーバーがUTF-8を想定している場合、送信する必要があるのは文字列ではなくバイトです。したがって、ピーターの答えに従って、最初の行でエンコードを指定し、2行目をドロップします。
Michael Borgwardt

@マイケル:本当の意図がここにあるのかはっきりしないことに同意します。人々が文字列とバイトの間でそれをさせるので{In,Out}putStream{Read,Writ}ersはなく、明示的な変換を試みようとしている多くの質問があるようです。なんでかしら?
tchrist

1
@マイケル:ありがとう、私はそれが理にかなっていると思います。しかし、それはまた、必要以上に難しくなりますね。私はそのように機能する言語があまり好きではないので、それらを使用しないようにしてください。バイトの代わりに文字の文字列のJavaのモデルは物事をずっと簡単にすると思います。PerlとPythonは、「すべてがUnicode文字列である」モデルも共有しています。はい、3つすべてで作業してもバイト単位で取得できますが、実際には本当に必要なことはまれです。それは非常に低レベルです。それに、私が何を言っているのか知っていれば、猫を間違った方向にブラッシングするような感じがします。:)
tchrist

回答:


140

String Javaのオブジェクトは、変更できないUTF-16エンコーディングを使用します。

別のエンコーディングを持つことができる唯一のものはbyte[]です。したがって、UTF-8データが必要な場合は、byte[]String予期しないデータを含むがある場合、問題はいくつかのバイナリデータを誤ってaに変換した以前の場所にありますString(つまり、間違ったエンコーディングを使用していました)。


92
技術的には、byte []に​​はエンコーディングがありません。ただし、バイト配列PLUSエンコーディングを使用すると、文字列を取得できます。
PeterŠtibraný2011

1
@ピーター:本当。ただし、エンコーディングを添付しても意味があるだけで、意味がbyte[]ありませんString(エンコーディングがUTF-16である場合を除き、その場合は意味がありますが、それでもなお不必要な情報です)。
Joachim Sauer

4
String objects in Java use the UTF-16 encoding that can't be modified. この見積もりの​​公式ソースはありますか?
Ahmad Hajjar 2018年

@ AhmadHajjardocs.oracle.com / javase/ 10 / docs/ api / java / lang/ :「Javaプラットフォームは、char配列とStringおよびStringBufferクラスでUTF-16表現を使用します。」
Maxi Gis

173

使ってみて

ByteBuffer byteBuffer = StandardCharsets.UTF_8.encode(myString)

ピーターとの私の議論を見てください。しかし、質問についての彼の仮定が正しい場合、ByteBufferを返すため、ソリューションはまだ考えられません。
Michael Borgwardt、2011

8
しかし、エンコードされた文字列を取得するにはどうすればよいですか?ByteBufferを返します
Alex

7
@Alex:UTF-8でエンコードされたJava文字列を持つことはできません。バイトが必要なため、ByteBufferを直接使用するか(ネットワークコレクションを介して送信することが目的の場合は、最善の解決策になる可能性もあります)、またはその上でarray()を呼び出してバイトを取得します[]
Michael Borgwardt

2
UnsupportedEncodingExceptionをスローする可能性のある文字列の代わりに、GuavaのCharsets.UTF_8 enumを使用することが役立つ場合があります。文字列->バイト:myString.getBytes(Charsets.UTF_8)、およびバイト->文字列:new String(myByteArray, Charsets.UTF_8)
laughing_man

24
さらに、を使用しますStandardCharsets.UTF_8。Java 1.7以降で使用できます。
Kat 14

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、2015

6.で動作します。ありがとうございます。
Itik Mauyhas 2017

私も正解です。ただし、上記のように使用すると、ドイツ語の文字が?に変わりました。そこで、私はこれを使用しました:byte [] ptext = myString.getBytes(UTF_8); 文字列値= new String(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
@Michael:彼は明らかに文字列からバイトを取得するのに問題を抱えています。getBytes(encoding)はどのようにポイントを逃していますか?2行目は、彼が元に戻すことができるかどうかを確認するためだけにあると思います。
PeterŠtibraný11年

1
私はそれを文字列が壊れていて、バイトに変換して戻すことで「修正」しようとしていると解釈します(よくある誤解)。2行目が結果を確認しているだけであるという実際の兆候はありません。
Michael Borgwardt

@マイケル、いいえ、それは私の解釈です。あなたのものは単に異なります。
PeterŠtibraný2011

1
@ピーター:その通りです、アレックスから彼の本当の意味を説明する必要があります。回答が編集されない限り、反対票を取り消すことはできません...
Michael Borgwardt

33

Java Stringは内部的に常にUTF-16でエンコードされますが、実際には次のように考える必要があります。エンコードは、文字列とバイトの間で変換する方法です。

したがって、エンコーディングに問題がある場合は、文字列を取得するまでに修正するのは遅すぎます。ファイル、DB、またはネットワーク接続からその文字列を作成する場所を修正する必要があります。


1
文字列が内部的にUTF-16でエンコードされていると信じるのはよくある間違いです。通常はそうですが、そうである場合は、Stringクラスの実装固有の詳細にすぎません。文字データの内部ストレージにはパブリックAPIからアクセスできないため、特定のString実装が他のエンコーディングを使用することを決定する場合があります。
jarnbjo 2011

3
@jarnbjo:APIは「文字列はUTF-16形式の文字列を表す」と明示的に述べています。他のものを内部フォーマットとして使用することは非常に非効率的であり、私が知っているすべての実際の実装は内部でUTF-16を使用しています。だからあなたがそうしないものを引用することができない限り、あなたはかなり不合理なヘアスプリッティングに従事しています。
Michael Borgwardt、2011

公開アクセスとデータ構造の内部表現を区別するのはばかげたことですか?
jarnbjo 2011

5
JVM(VMに関連する限り)は、たとえばクラスファイル内の文字列エンコーディングにUTF-8を使用します。java.lang.Stringの実装はJVMから切り離されており、答えが正しくないことを理解するために本当に必要な場合は、内部表現に他のエンコーディングを使用してクラスを簡単に実装できます。内部フォーマットとしてUTF-16を使用すると、メモリ消費に関してもほとんどの場合非常に非効率的です。たとえば、組み込みハードウェアのJava実装がパフォーマンスの代わりにメモリを最適化しない理由はわかりません。
jarnbjo 2011

1
@jarnbjo:そしてもう一度:標準のAPI実装内部でUTF-16以外のものを使用して文字列を実装しているJVMの具体例を提供できない限り、私の文は正しいです。そして、いいえ。Stringクラスは、intern()や定数プールなどの理由により、JVMから実際には分離されていません。
Michael Borgwardt、2011

22

この方法を試すことができます。

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

1
私は夢中になりました。最初に「ISO-8859-1」のバイトを取得していただき、ありがとうございます。
Gian Gomen

2
これは間違っています。文字列にUnicode文字が含まれている場合、8859-1に変換すると例外がスローされるか、無効な文字列(コードポイント0x100以上の文字がない文字列)が発生する可能性があります。
Alexis Wilke

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.