在Java中将Windows-1252转换为UTF-16

mspsb9vt  于 2022-09-21  发布在  Java
关注(0)|答案(3)|浏览(283)

我正在尝试将所有Windows特殊字符转换为它们的Unicode等效项。我们有一个Flex应用程序,用户在其中保存一些富文本,然后通过Java电子邮件程序将其通过电子邮件发送给他们的收件人。然而,我们经常遇到Word的特殊字符,这些字符在电子邮件中只显示为?

到目前为止,我已经试过了

private String replaceWordChars(String text_in) {
    String s = text_in;

    // smart single quotes and apostrophe
    s = s.replaceAll("[\u2018|\u2019|\u201A]", "'");
    // smart double quotes
    s = s.replaceAll("[\u201C|\u201D|\u201E]", """);
    // ellipsis
    s = s.replaceAll("\u2026", "...");
    // dashes
    s = s.replaceAll("[\u2013|\u2014]", "-");
    // circumflex
    s = s.replaceAll("\u02C6", "^");
    // open angle bracket
    s = s.replaceAll("\u2039", "<");
    // close angle bracket
    s = s.replaceAll("\u203A", ">");
    // spaces
    s = s.replaceAll("[\u02DC|\u00A0]", " ");

    return s;

这是可行的,但我不想将所有Windows-1252字符手动编码为它们的等效UTF-16(假设这是默认的Java字符集)

然而,我们的用户不断从Microsoft Word中找到更多Java无法处理的字符。所以我找了又找,找到了这个例子

private String replaceWordChars(String text_in) {
    String s = text_in;
    try {
        byte[] b = s.getBytes("Cp1252");
        byte[] encoded = new String(b, "Cp1252").getBytes("UTF-16");
        s = new String(encoded, "UTF-16");

    } catch (UnsupportedEncodingException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    return s;

但是,当我观察到在Eclipse调试器中进行编码时,什么都没有改变。

必须有一个简单的解决方案来处理微软用Java进行的可爱的编码。

有什么想法吗?

bqucvtff

bqucvtff1#

您可以尝试使用java.nio.charset.Charset

final Charset windowsCharset = Charset.forName("windows-1252");
final Charset utfCharset = Charset.forName("UTF-16");
final CharBuffer windowsEncoded = windowsCharset.decode(ByteBuffer.wrap(new byte[] {(byte) 0x91}));
final byte[] utfEncoded = utfCharset.encode(windowsEncoded).array();
System.out.println(new String(utfEncoded, utfCharset.displayName()));
cbjzeqam

cbjzeqam2#

使用以下步骤:

1.使用源文件的编码创建InputStreamReader(Windows-1252)
1.使用目标文件的编码(UTF-16)创建OutputStreamWriter
1.将从读取器读取的信息复制到写入器。您可以使用BufferedReaderBufferedWriter逐行写入内容。

因此,您的代码可能如下所示:

public void reencode(InputStream source, OutputStream dest,
        String sourceEncoding, String destEncoding)
        throws IOException {
    BufferedReader reader = new BufferedReader(new InputStreamReader(source, sourceEncoding));
    BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(dest, destEncoding));
    String in;
    while ((in = reader.readLine()) != null) {
        writer.write(in);
        writer.newLine();
    }
}

当然,这排除了try/Catch内容,并将其委托给调用者。

如果您只是试图以排序字符串的形式获取内容,则可以用StringWriter替换writer并返回其toString值。然后,您不需要目的地流或编码,只需要一个转储字符的地方:

public String decode(InputStream source, String sourceEncoding)
        throws IOException {
    BufferedReader reader = new BufferedReader(new InputStreamReader(source, sourceEncoding));
    StringWriter writer = new StringWriter();
    String in;
    while ((in = reader.readLine()) != null) {
        writer.write(in);
        writer.write('n'); // Java newline should be fine, test this just in case
    }
    return writer.toString();
}
3bygqnnd

3bygqnnd3#

到目前为止,似乎对我测试过的所有东西都有效的是:

private String replaceWordChars(String text_in) {
    String s = text_in;

    final Charset windowsCharset = Charset.forName("windows-1252");
    final Charset utfCharset     = Charset.forName("UTF-16");

    byte[] incomingBytes = s.getBytes();
    final CharBuffer windowsEncoded = 
        windowsCharset.decode(ByteBuffer.wrap(incomingBytes)); 

    final byte[] utfEncoded = utfCharset.encode(windowsEncoded).array();
    s = new String(utfEncoded);

    return s;
}

相关问题