识别和匹配文件中的非 ascii 字符
Identifying and matching non ascii characters in files
我正在尝试读取带分隔符的文件并解析其内容。与 CSV 不同,分隔符、字符串限定符等是非 ASCII 的,即。分别为 U0014 和 U00FE。但是,我无法检测到字符串限定符 (FE) 。这是因为字符的值大于 128 还是其他?
这是一个说明核心问题的简单程序。我怎样才能使这项工作?这是一个非常小的测试文件的 link。 https://www.dropbox.com/s/1cilircwc3pq78c/nonascii.dat?dl=0
谢谢
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.LineIterator;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.io.Reader;
public class CharMatch {
public static void main(String[] args)
throws Exception {
final String pathname = "/home/vinayb/Downloads/nonascii.dat";
final File file = new File(pathname);
final String encoding = "UTF-8";
final PrintStream out = new PrintStream(System.out, true, encoding);
final Reader r = new BufferedReader(new InputStreamReader(
new FileInputStream(file), encoding));
final LineIterator it = FileUtils.lineIterator(file, encoding);
try {
//read a line
final String line = it.nextLine();
final char[] chars = line.toCharArray();
for (char c : chars) {
out.println(c + " , with decimal value: " + Character.getNumericValue(c) + " and hexa value: " + Integer.toHexString(Character.getNumericValue(c)));
}
out.println("------------------------------------");
final String expectedDelimiter = fromUnicode("0014");
final String expectedStringQualifier = fromUnicode("00FE");
out.println("##### expected delimiter:" + expectedDelimiter);
out.println("##### expected string qualifier:" + expectedStringQualifier);
String[] items = line.split(expectedDelimiter);
out.println("#### " + items.length + " " + items[0]);
if (line.contains(expectedDelimiter)) {
out.println("Found delimiter"); ////=======> can match this
}
if (line.contains(expectedStringQualifier)) {
out.println("Found string qualifier"); //=======> can't match this
}
} finally {
LineIterator.closeQuietly(it);
}
}
private static String fromUnicode(String codePoint) {
return "" + (char) Integer.parseInt(codePoint, 16);
}
}
您的文件不是有效的 UTF-8:
$ iconv -f utf-8 *dat >/dev/null; echo $?
iconv: illegal input sequence at position 0
1
但它可以是 "read" 作为 ISO-8859-1:
$ iconv -f iso-8859-1 *dat >/dev/null; echo $?
0
只需将编码更改为该编码即可;但是这样的文件格式在2015年就比较奇怪了。你真正应该做的是要求这些文件的来源与时俱进;)
请注意,由于第一个字节序列无效,默认情况下 Java 会将其替换为 U+FFFD;它将对无法转换为 char
的每个字节序列执行此操作。即使在这种情况下,为了让 Java 抛出异常,您需要实例化一个 CharsetDecoder
(来自 Charset
实例)并指定您想要 .onMalformedInput(CodingErrorAction.REPORT)
(默认为 CodingErrorAction.REPLACE
).
看看here。 00 FE 可能是 UTF-16 的正确代码,但在 UTF-8 中它是 C3 BE。这也可以解释为什么它不是有效的 UTF-8。
我正在尝试读取带分隔符的文件并解析其内容。与 CSV 不同,分隔符、字符串限定符等是非 ASCII 的,即。分别为 U0014 和 U00FE。但是,我无法检测到字符串限定符 (FE) 。这是因为字符的值大于 128 还是其他?
这是一个说明核心问题的简单程序。我怎样才能使这项工作?这是一个非常小的测试文件的 link。 https://www.dropbox.com/s/1cilircwc3pq78c/nonascii.dat?dl=0
谢谢
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.LineIterator;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.io.Reader;
public class CharMatch {
public static void main(String[] args)
throws Exception {
final String pathname = "/home/vinayb/Downloads/nonascii.dat";
final File file = new File(pathname);
final String encoding = "UTF-8";
final PrintStream out = new PrintStream(System.out, true, encoding);
final Reader r = new BufferedReader(new InputStreamReader(
new FileInputStream(file), encoding));
final LineIterator it = FileUtils.lineIterator(file, encoding);
try {
//read a line
final String line = it.nextLine();
final char[] chars = line.toCharArray();
for (char c : chars) {
out.println(c + " , with decimal value: " + Character.getNumericValue(c) + " and hexa value: " + Integer.toHexString(Character.getNumericValue(c)));
}
out.println("------------------------------------");
final String expectedDelimiter = fromUnicode("0014");
final String expectedStringQualifier = fromUnicode("00FE");
out.println("##### expected delimiter:" + expectedDelimiter);
out.println("##### expected string qualifier:" + expectedStringQualifier);
String[] items = line.split(expectedDelimiter);
out.println("#### " + items.length + " " + items[0]);
if (line.contains(expectedDelimiter)) {
out.println("Found delimiter"); ////=======> can match this
}
if (line.contains(expectedStringQualifier)) {
out.println("Found string qualifier"); //=======> can't match this
}
} finally {
LineIterator.closeQuietly(it);
}
}
private static String fromUnicode(String codePoint) {
return "" + (char) Integer.parseInt(codePoint, 16);
}
}
您的文件不是有效的 UTF-8:
$ iconv -f utf-8 *dat >/dev/null; echo $?
iconv: illegal input sequence at position 0
1
但它可以是 "read" 作为 ISO-8859-1:
$ iconv -f iso-8859-1 *dat >/dev/null; echo $?
0
只需将编码更改为该编码即可;但是这样的文件格式在2015年就比较奇怪了。你真正应该做的是要求这些文件的来源与时俱进;)
请注意,由于第一个字节序列无效,默认情况下 Java 会将其替换为 U+FFFD;它将对无法转换为 char
的每个字节序列执行此操作。即使在这种情况下,为了让 Java 抛出异常,您需要实例化一个 CharsetDecoder
(来自 Charset
实例)并指定您想要 .onMalformedInput(CodingErrorAction.REPORT)
(默认为 CodingErrorAction.REPLACE
).
看看here。 00 FE 可能是 UTF-16 的正确代码,但在 UTF-8 中它是 C3 BE。这也可以解释为什么它不是有效的 UTF-8。