【问题标题】:Read/write .txt file with special characters读/写带有特殊字符的 .txt 文件
【发布时间】:2011-01-04 19:53:01
【问题描述】:

我打开记事本(Windows)并写

Some lines with special characters
Special: Žđšćč

然后转到另存为...“someFile.txt”,Encoding 设置为 UTF-8

在 Java 中我有

FileInputStream fis = new FileInputStream(new File("someFile.txt"));
InputStreamReader isr = new InputStreamReader(fis, "UTF-8");
BufferedReader in = new BufferedReader(isr);

String line;
while((line = in.readLine()) != null) {                         
    printLine(line);
}
in.close();

但我得到问号和类似的“特殊”字符。为什么?

编辑:我有这个输入(.txt 文件中的一行)

665,Žđšćč

还有这段代码

FileInputStream fis = new FileInputStream(new File(fileName));
InputStreamReader isr = new InputStreamReader(fis, "UTF-8");
BufferedReader in = new BufferedReader(isr);

String line;
while((line = in.readLine()) != null) {
    Toast.makeText(mContext, line, Toast.LENGTH_LONG).show();

    Pattern p = Pattern.compile(",");
    String[] article = p.split(line);

    Toast.makeText(mContext, article[0], Toast.LENGTH_LONG).show();
    Toast.makeText(mContext, Integer.parseInt(article[0]), Toast.LENGTH_LONG).show();
}
in.close();

Toast 输出(对于不熟悉 Android 的人来说,Toast 只是一种在屏幕上显示带有特定文本的弹出窗口的方法)很好。控制台显示“奇怪的字符”(可能是因为控制台窗口中的编码)。但它在解析整数时失败,因为控制台这么说 (warning: toast output is just fine) - Problem?

似乎字符串包含一些 Toast 无法显示/呈现的“奇怪”字符,但是当我尝试解析它时,它崩溃了。有什么建议吗?

如果我将 ANSI 放在记事本中,它可以工作(整数解析)并且没有上图中的奇怪字符,但是我的特殊字符当然不能工作。

【问题讨论】:

  • printLine(line) 函数中有什么?
  • while((line = in.readLine()) != null) - Java 甚至允许你这样做吗?我认为在 Java 中,赋值不被视为表达式......
  • @Will printLine 只是将它打印到我的调试器 (Eclipse) - 在这种情况下,第二行变为“01-04 20:01:23.394: VERBOSE/line(32246): Special: ŽÄÅ¡ÄÄ”
  • while((line = in.readLine()) != null) - 是的,你可以这样做 Eric。 while 循环正在评估的条件是 (A != null),其中 A 是从 in 流中读取一行的结果。
  • 实际上我的问题有点不同,实际上我的文件名是Žđšćč,我收到错误 FileInputStream fis = new FileInputStream(new File("Žđšćč.txt"));请帮忙

标签: java android eclipse file-io character-encoding


【解决方案1】:

输出控制台不支持这些字符。由于您使用的是 Eclipse,因此您需要确保将其配置为使用 UTF-8。您可以通过 Window > Preferences > General > Workspace > Text File Encoding > set to UTF-8 来做到这一点

另见:


更新 根据更新后的问题和 cmets,显然 UTF-8 BOM 是罪魁祸首。默认情况下,记事本会在保存时添加 UTF-8 BOM。看起来您的 HTC 上的 JRE 并没有吞下它。您可能需要考虑在代码中使用this answer 中概述的UnicodeReader 示例,而不是InputStreamReader。它会自动检测并跳过 BOM。

FileInputStream fis = new FileInputStream(new File(fileName));
UnicodeReader ur = new UnicodeReader(fis, "UTF-8");
BufferedReader in = new BufferedReader(ur);

与实际问题无关,最好关闭 finally 块中的资源,以确保在出现异常时关闭它们。

BufferedReader reader = null;
try {
    reader = new BufferedReader(new UnicodeReader(new FileInputStream(fileName), "UTF-8"));
    // ...
} finally {
    if (reader != null) try { reader.close(); } catch (IOException logOrIgnore) {}
}

同样不相关,我建议将 Pattern p = Pattern.compile(","); 放在循环之外,甚至将其设为静态常量,因为编译它的成本相对较高,而且没有必要每次都在循环内这样做。

【讨论】:

  • 这不是因为我的 SQLite INSERT 也不起作用。如果我手动输入(在我的 HTC Desire 上)作为输入“žđšćč”并将其转发到 INSERT 语句 - 它工作正常。但是,如果我使用读取功能从我的 .txt 文件中读取这些相同的字符 - 崩溃。所以,它不仅仅是控制台输出。还有什么?
  • 我更新了上面的代码...我真的不知道到底发生了什么=/
  • 现在在输出控制台上看起来是否正确?另一个原因可能是您的 SQLite JDBC 驱动程序和/或数据库未将字符视为 UTF-8。
  • 这里是部分答案 - stackoverflow.com/questions/4599061/unable-to-parse-as-integer。文档(.txt 文件)是 UTF-8,但为什么我的阅读器没有将其读取为 UTF-8?
【解决方案2】:

您的代码看起来正确 - 但一个非常常见且简单的错误是将打印到屏幕的内容误认为字符串中的内容。如果字符串尚未正确读取,请使用调试器检查。

【讨论】:

    【解决方案3】:

    记事本无法正确保存特殊符号。我遇到了类似的问题,我改用 Notepad++ 并从那里选择了 UTf-8 编码。当我这样做时,我的程序在应用 String 库方法时不再崩溃,这与我在记事本中创建文本文件时不同。

    【讨论】:

      【解决方案4】:

      记事本可能无法处理非 ASCII 字符。尝试其他文本编辑器。如果您想坚持使用 Windows 安装中可用的内容,请尝试写字板。

      【讨论】:

      • 他在记事本的另存为选项中选择了UTF-8。
      • 如果我使用写字板并将其另存为“文本文档”,它会在第二行失败。如果我使用 unicode 文本格式,它会在开始时崩溃。
      【解决方案5】:
      "Not all sequences of bytes are valid UTF-8."
      

      http://en.wikipedia.org/wiki/UTF-8

      在“无效的字节序列”下了解具体细节。

      【讨论】:

        【解决方案6】:

        您是否使用字符转换作为 servlet 请求/响应的一部分? 如是, request.setEncoding("UTF-8")

        response.setCharacterEncoding("UTF-8")

        应该解决你的目的。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2017-10-02
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-01-28
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多