Подтвердить что ты не робот

Какая разница между строкой в ​​исходном коде и строкой, считанной из файла?

на моем диске есть файл с именем "dd.txt", содержимое \u5730\u7406

теперь, когда я запускаю эту программу

public static void main(String[] args) throws IOException {
    FileInputStream fis=new FileInputStream("d:\\dd.txt");
    ByteArrayOutputStream baos=new ByteArrayOutputStream();
    byte[] buffer=new byte[fis.available()];
    while ((fis.read(buffer))!=-1) {
        baos.write(buffer);
    }
    String s1="\u5730\u7406";
    String s2=baos.toString("utf-8");
    System.out.println("s1:"+s1+"\n"+"s2:"+s2);
}

и я получил другой результат

s1:地理
s2:\u5730\u7406

Можете ли вы сказать мне, почему? и как я могу прочитать этот файл и получить тот же результат, что и s1 на китайском языке?

4b9b3361

Ответ 1

Когда вы пишете \u5730 в Java-коде, он интерпретируется как один символ юникода (литерал в Юникоде) компилятором. Когда вы пишете то же самое в файле, это всего лишь 6 обычных символов (потому что там ничего не интерпретируется). Есть ли причина, по которой вы не пишете 地理 непосредственно в файл?

Если вы хотите прочитать файл, содержащий литералы в формате Юникода, вам нужно будет самостоятельно проанализировать значения, отбросив \u и разобрать код юникода самостоятельно. Гораздо проще просто написать правильный юникод с подходящей кодировкой (например, UTF-8) в файле в первую очередь, если вы контролируете создание файла, и при нормальных обстоятельствах вам никогда не придется сталкиваться с файлами, содержащими эти escape-последовательности в кодировке unicode.

Ответ 2

В вашем Java-коде \uxxxx интерпретируются как литералы Юникода, поэтому они отображаются как китайские символы. Это делается только потому, что компилятору дается указание сделать это.

Чтобы получить тот же результат, вам нужно выполнить парсинг самостоятельно:

String[] hexCodes = s2.split("\\\\u");
for (String hexCode : hexCodes) {
    if (hexCode.length() == 0)
        continue;
    int intValue = Integer.parseInt(hexCode, 16);
    System.out.print((char)intValue);
}

(обратите внимание, что это работает только в том случае, если каждый символ находится в литеральной форме Unicode, например \uxxxx)

Ответ 3

Попробуйте следующее:

static final Pattern UNICODE_ESCAPE = Pattern.compile("\\\\u([0-9a-fA-F]{4})");

static String decodeUnicodeEscape(String s) {
    StringBuilder sb = new StringBuilder();
    int start = 0;
    Matcher m = UNICODE_ESCAPE.matcher(s);
    while (m.find()) {
        sb.append(s.substring(start, m.start()));
        sb.append((char)Integer.parseInt(m.group(1), 16));
        start = m.end();
    }
    sb.append(s.substring(start));
    return sb.toString();
}

public static void main(String[] args) throws IOException {
    // your code ....
    String s1="\u5730\u7406";
    String s2= decodeUnicodeEscape(baos.toString("utf-8"));
    System.out.println("s1:"+s1+"\n"+"s2:"+s2);
}