Google App EngineでWebアプリケーションを作成しています。基本的に、ブロブストアに.html
ファイルとして保存されるHTMLコードを編集できます。
FetchDataを使用して、ファイル内のすべての文字のbyte[]
を返します。ユーザーがhtmlコードを編集できるように、htmlに印刷しようとしています。すべてがうまくいきます!
ここに私の唯一の問題があります:
文字列に変換するときに、バイト配列に問題があります。スマート引用符といくつかのキャラクターがファンキーに見えます。 (?や日本語の記号など)具体的には、問題を引き起こしている負の値を持っているのは数バイトです。
スマート引用符は、バイト配列で-108
および-109
として返されます。これはなぜですか?正しい文字エンコーディングを表示するために負のバイトをデコードするにはどうすればよいですか?
バイト配列には、特別なエンコーディング(知っておくべき)の文字が含まれています。文字列に変換する方法は次のとおりです。
String decoded = new String(bytes, "UTF-8"); // example for one encoding type
ちなみに、Javaデータ型byte
が署名されているという理由だけで、生のバイトが負の小数として表示される場合があり、それは-128から127の範囲をカバーします。
-109 = 0x93: Control Code "Set Transmit State"
値(-109)は、UNICODEの印刷不可能な制御文字です。したがって、UTF-8はその文字ストリームの正しいエンコードではありません。
「Windows-1252」の0x93
は探している「スマートクォート」なので、そのエンコーディングのJava名は「Cp1252」です。次の行はテストコードを提供します。
System.out.println(new String(new byte[]{-109}, "Cp1252"));
Java 7以降
StandardCharsets からString
定数として希望のエンコードをCharset
コンストラクターに渡すこともできます。これは、他の回答で提案されているように、エンコードをString
として渡すよりも安全です。
たとえば、UTF-8エンコードの場合
String bytesAsString = new String(bytes, StandardCharsets.UTF_8);
これを試すことができます。
String s = new String(bytearray);
public class Main {
/**
* Example method for converting a byte to a String.
*/
public void convertByteToString() {
byte b = 65;
//Using the static toString method of the Byte class
System.out.println(Byte.toString(b));
//Using simple concatenation with an empty String
System.out.println(b + "");
//Creating a byte array and passing it to the String constructor
System.out.println(new String(new byte[] {b}));
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
new Main().convertByteToString();
}
}
出力
65
65
A
public static String readFile(String fn) throws IOException
{
File f = new File(fn);
byte[] buffer = new byte[(int)f.length()];
FileInputStream is = new FileInputStream(fn);
is.read(buffer);
is.close();
return new String(buffer, "UTF-8"); // use desired encoding
}
Arrays.toString(byte_array);
をお勧めします
それはあなたの目的に依存します。たとえば、次のようなデバッグ時に表示される形式とまったく同じバイト配列を保存したかったのです:[1, 2, 3]
バイトを文字形式に変換せずにまったく同じ値を保存する場合は、Arrays.toString (byte_array)
がこれを行います。ただし、バイトではなく文字を保存する場合は、String s = new String(byte_array)
を使用する必要があります。この場合、s
は、文字の形式で[1, 2, 3]
と同等です。
Andreas_Dからの以前の回答は良いです。出力を表示する場所にフォントと文字エンコードがあり、一部の文字がサポートされていない可能性があることを追加します。
問題がJavaであるか、ディスプレイであるかを判断するには、次のようにします。
for(int i=0;i<str.length();i++) {
char ch = str.charAt(i);
System.out.println(i+" : "+ch+" "+Integer.toHexString(ch)+((ch=='\ufffd') ? " Unknown character" : ""));
}
Javaは、不明な文字の公式文字を0xfffdに理解できない文字をマッピングします。 「?」が表示された場合出力では0xfffdにマッピングされていませんが、問題はJavaではなくディスプレイフォントまたはエンコードです。