Java 从大文件中删除4字节UTF字符

Java 从大文件中删除4字节UTF字符,java,bash,multibyte,Java,Bash,Multibyte,我有一个包含多字节字符的文件。因为这个文件非常大,我想从这个文件中删除4字节的utf字符。我需要一个更快的解决方案。我为此任务尝试了以下java代码,但它导致java堆内存不足异常。所以 import java.util.*; import java.io.*; public class A{ public static void main(String args[]) throws Exception{ BufferedReader br = new BufferedReader(new

我有一个包含多字节字符的文件。因为这个文件非常大,我想从这个文件中删除4字节的utf字符。我需要一个更快的解决方案。我为此任务尝试了以下java代码,但它导致java堆内存不足异常。所以

import java.util.*;
import java.io.*;
public class A{
 public static void main(String args[]) throws Exception{
  BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
  String str=br.readLine();
  char[] c_array;
  String c_string;
  byte[] c_byte_array;
  c_array = str.toCharArray();
  for (char c : c_array){
   c_string = Character.toString(c);
   c_byte_array = c_string.getBytes("UTF-8");
   if (c_byte_array.length <= 3){
    System.out.print(c_string);
   }
  }
 }
}
但它存在一个错误

grep: range out of order in character class
所以我的问题是上面的正则表达式有什么问题。或者换句话说,什么是正则表达式以匹配4字节utf字符。
另一个问题是,上述哪种方法更有效地删除4字节字符

UTF-8 4字节字符是U+FFFF以上的Unicode字符(请参阅),它们在Java中由2个字符表示。我们可以使用Character.isSurrogate(参见API)来检测此类字符

    BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("1.txt"), "UTF-8"));
    for (int c; (c = br.read()) != -1;) {
        if (Character.isSurrogate((char)c)) {
            // skip the second surrogate char
            br.read();
        } else {
            // process char c
        }
    }
或者,如果您想过滤字节流,那么我们可以使用另一种解决方案,基于4字节字符UTF-8序列是

11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

因此,我们可以将字节流过滤为

   BufferedInputStream is = new BufferedInputStream(new FileInputStream("1.txt"));
    for (int b; (b = is.read()) != -1;) {
        if ((b & 0b11111000) == 0b11110000) {
            // skip next 3 bytes
            is.read();
            is.read();
            is.read();
        } else {
            // process byte b
        }
    }

嗯。。。压缩文件不是更好吗?压缩文件是为了什么?我是说我没听清你的问题?你为什么要从文件中删除随机字符?这就像你问“我想删除所有小写字母”一样奇怪,实际上我想在postgresql中导入的文件是mysqldump,不允许插入4字节UTF字符。转储文件的大小可能高达1-2GB。所以我需要一个解决方案fast@NarendraRajput-postgres如何声称支持utf-8而不支持4字节字符序列?你确定这一点吗?另外,你的代码将避免内存不足错误,因为他读取的是基于行的,行可以任意大。我认为
Character.isSupplementaryCodePoint(c)
更合适,不是吗?
   BufferedInputStream is = new BufferedInputStream(new FileInputStream("1.txt"));
    for (int b; (b = is.read()) != -1;) {
        if ((b & 0b11111000) == 0b11110000) {
            // skip next 3 bytes
            is.read();
            is.read();
            is.read();
        } else {
            // process byte b
        }
    }