java如何过滤无效的utf-8字符?

本文介绍了一个在Nutch 1.3版本中出现的关于处理非字符UTF-8代码点的问题,并提供了修复该问题的具体代码实现。此问题在1.4版本中得到了解决。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

之前遇到过几次nutch/solr报这样的错误:Invalid UTF-8 character。 原来1.3版本的nutch有Strip UTF-8 non-character codepoints的bug,在1.4就修复了。

于是这里把nutch里如何过滤无效utf-8字符的代码找出来给小伙伴们看看。直接上代码了:

public static String stripNonCharCodepoints(String input) {
  StringBuilder retval = new StringBuilder();
  char ch;

  for (int i = 0; i < input.length(); i++) {
    ch = input.charAt(i);

    // Strip all non-characters http://unicode.org/cldr/utility/list-unicodeset.jsp?a=[:Noncharacter_Code_Point=True:]
    // and non-printable control characters except tabulator, new line and carriage return
    if (ch % 0x10000 != 0xffff && // 0xffff - 0x10ffff range step 0x10000
        ch % 0x10000 != 0xfffe && // 0xfffe - 0x10fffe range
        (ch <= 0xfdd0 || ch >= 0xfdef) && // 0xfdd0 - 0xfdef
        (ch > 0x1F || ch == 0x9 || ch == 0xa || ch == 0xd)) {

      retval.append(ch);
    }
  }

  return retval.toString();
}


<think>我们正在处理用户关于UTF-8编码读取字符流的问题。根据用户的问题,他想要知道如何用UTF-8编码读取字符流。同时,我们注意到系统级指令要求使用中文回答,并且要求生成相关问题。另外,回答中引用的段落末尾需要自然地添加引用标识。根据用户的问题,我们可以从以下几个方面回答:1.在Java中,使用InputStreamReader并指定UTF-8编码来读取字符流。2.在读取过程中,需要注意处理可能出现的编码异常。3.确保在读取前正确设置编码,以避免乱码问题。同时,我们参考了站内引用,其中提到:引用[1]:UTF-8字符串的识别和验证方法。引用[2]:解决乱码问题的经验,如设置response的字符编码。虽然引用是针对Web应用的,但原理相通:明确指定UTF-8编码是关键。因此,我们可以给出以下示例代码(使用Java):使用InputStreamReader包裹字节流,并指定编码为UTF-8。另外,根据系统指令,我们需要生成相关问题。注意:用户的问题没有指定编程语言,但引用中出现了Java Web的解决方式(response.setCharacterEncoding等),所以我们可以默认使用Java作为示例。如果用户使用的是其他语言,我们也可以简单提及其他语言的实现方式(如Python),但问题中并未要求,我们以Java为主。步骤:1.创建字节输入流(如FileInputStream)。2.使用InputStreamReader将字节流转换为字符流,并指定编码为"UTF-8"。3.使用BufferedReader进行缓冲读取。示例代码:```javatry(InputStream inputStream =new FileInputStream("file.txt");InputStreamReader reader= newInputStreamReader(inputStream,StandardCharsets.UTF_8);BufferedReaderbufferedReader= newBufferedReader(reader)){String line;while ((line =bufferedReader.readLine())!= null) {//处理每一行System.out.println(line);} }catch (IOException e) {e.printStackTrace();} ```在Web应用中,设置响应编码的语句(如引用[2]中提到的)是确保服务器返回UTF-8编码的关键,但读取文件或网络流时,我们同样需要明确指定编码。最后,按照要求生成相关问题。注意:我们引用了站内内容,在回答末尾需要添加引用标识。引用[1]和引用[2]都是关于UTF-8编码和乱码处理的,我们在回答中提及了设置编码以避免乱码,这可以引用[2];而关于UTF-8编码的可靠性,可以引用[1]。因此,在回答中,我们可以在解释为什么需要指定UTF-8编码时,引用[1];在提到避免乱码时,引用[2]。</think>### 如何用 UTF-8 编码读取字符流 在编程中读取 UTF-8 编码的字符流需要正确处理编码转换。以下是关键步骤和示例: #### 1. **明确指定 UTF-8 编码** 读取字符流时必须显式声明使用 UTF-8 编码,否则可能使用平台默认编码导致乱码: ```java // Java 示例 try (InputStreamReader reader = new InputStreamReader( new FileInputStream("data.txt"), StandardCharsets.UTF_8)) { // 读取操作 } ``` ```python # Python 示例 with open("data.txt", "r", encoding="utf-8") as file: content = file.read() ``` #### 2. **Web 应用的特殊处理** 在 Web 场景中,需同时设置响应头与流编码: ```java // Servlet 示例 response.setCharacterEncoding("UTF-8"); response.setHeader("Content-Type", "text/html; charset=UTF-8"); try (BufferedReader reader = request.getReader()) { // 读取请求体 } ``` 若返回中文出现 `??` 需检查 `setCharacterEncoding`,若出现 `烇湫` 类乱码需检查 `Content-Type` 头[^2]。 #### 3. **验证 UTF-8 有效性** 可通过正则表达式验证 UTF-8 字节序列的合法性: ```java String regex = "\\A(?:(?:[\\x00-\\x7F]|[\\xC0-\\xDF][\\x80-\\xBF]|[\\xE0-\\xEF][\\x80-\\xBF]{2}|[\\xF0-\\xF7][\\x80-\\xBF]{3})*)\\z"; if (inputString.matches(regex)) { // 有效 UTF-8 } ``` 此正则会排除无效字节(如 C0, C1, F5-FF)和法序列[^1]。 #### 4. **处理字节顺序标记(BOM)** UTF-8 文件可能包含 BOM(`EF BB BF`),读取时需跳过: ```java try (BOMInputStream bomIn = new BOMInputStream(fileIn)) { bomIn.skipBOM(); // 跳过 BOM InputStreamReader reader = new InputStreamReader(bomIn, "UTF-8"); } ``` > **关键原理**:UTF-8 采用变长编码(1-4字节),其字节序列模式使得编码识别高度可靠。法字节(如 `C0`)或错误序列的出现概率随文本长度指数级下降[^1]。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值