Java中的iconv等效代码不';我不能返回相同的结果
我需要将文件从UTF-8编码到Shift_JIS。以前,这是使用iconv命令完成的,如下所示Java中的iconv等效代码不';我不能返回相同的结果,java,encoding,iconv,Java,Encoding,Iconv,我需要将文件从UTF-8编码到Shift_JIS。以前,这是使用iconv命令完成的,如下所示 iconv -f utf8 -t sjis $INPUT_FILE 我提供的输入文件返回一个错误,即 位置2551处的非法输入序列 我编写了以下Java代码: FileInputStream fis = new FileInputStream( "Input.txt"); InputStreamReader in = new InputStreamReader(fis, "UTF-
iconv -f utf8 -t sjis $INPUT_FILE
我提供的输入文件返回一个错误,即
位置2551处的非法输入序列
我编写了以下Java代码:
FileInputStream fis = new FileInputStream(
"Input.txt");
InputStreamReader in = new InputStreamReader(fis, "UTF-8");
FileOutputStream fos = new FileOutputStream("Output.txt");
OutputStreamWriter out = new OutputStreamWriter(fos, "Shift_JIS");
int val = 0;
StringBuilder sb = new StringBuilder();
while((val =in.read() )!= -1){
System.out.println(Integer.toHexString(val));
sb.append((char)val);
}
out.write(sb.toString());
out.flush();
fis.close();
out.close();
使用相同的输入文件,代码可以正常执行,并且不会返回任何错误
我有什么遗漏吗
约阿希姆。这看起来是答案。我在问题中添加了我的代码。我现在得到不可映射的字符错误。但它无法像任何文本“hello”那样对普通字符进行编码。我哪里做错了
private static CharsetDecoder decoder(String encoding) {
return Charset.forName(encoding).newDecoder()
.onMalformedInput(CodingErrorAction.REPORT)
.onUnmappableCharacter(CodingErrorAction.REPORT);
}
private static CharsetEncoder encoder(String encoding) {
return Charset.forName(encoding).newEncoder()
.onMalformedInput(CodingErrorAction.REPORT)
.onUnmappableCharacter(CodingErrorAction.REPORT);
}
public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream(
"D:\\Input.txt");
InputStreamReader in = new InputStreamReader(fis, decoder("UTF-8"));
FileOutputStream fos = new FileOutputStream("D:\\Output.txt");
OutputStreamWriter out = new OutputStreamWriter(fos, encoder("Shift_JIS"));
char[] buffer = new char[4096];
int length;
while ((length = in.read(buffer)) != -1) {
out.write(buffer, 0, length);
}
out.flush();
}
这应该只是UTF-8的一个问题。只需执行一个InputStream并从位置2551开始十六进制转储,或者前面的文本稍早一点 特别有趣的是,iconv在那里提供了什么
转储: 因此,我们可以看到是哪些数据导致了问题
public static void main(String[] args) {
try (BufferedInputStream in = new BufferedInputStream(
new FileInputStream("D:\\input.txt"))) {
dumpBytes(in, 2551 - 10, 20);
} catch (IOException ex) {
ex.printStackTrace();
}
}
private static void dumpBytes(InputStream in, long offset, int length)
throws IOException {
long pos = in.skip(offset);
while (length >= 0) {
int b = in.read();
if (b == -1) {
break;
}
b &= 0xFF;
System.out.printf("%6d: 0x%02x %s '%c'%n", pos, b,
toBinaryString(b), (32 <= b && b < 127 ? (char)b : '?'));
--length;
++pos;
}
}
private static String toBinaryString(int b) {
String s = Integer.toBinaryString(b);
s = "00000000" + s;
s = s.substring(s.length() - 8);
s = s.substring(0, 4) + "_" + s.substring(4);
return s;
}
publicstaticvoidmain(字符串[]args){
try(BufferedInputStream in=new BufferedInputStream)(
新文件输入流(“D:\\input.txt”)){
转储字节(in,2551-10,20);
}捕获(IOEX异常){
例如printStackTrace();
}
}
专用静态void dumpBytes(InputStream-in、long offset、int-length)
抛出IOException{
长位置=英寸跳跃(偏移);
while(长度>=0){
int b=in.read();
如果(b==-1){
打破
}
b&=0xFF;
System.out.printf(“%6d:0x%02x%s”%c“%n”,位置,b,
toBinaryString(b),(32)我不确定tat会有什么帮助。你能解释一下吗?这不是获得分数的解决方案,但2551处的字节序列必须是损坏的UTF-8(“非法输入序列”).知道字节/位,就可以很容易地看出这是否确实是非法的UTF-8,也许还可以从中扣除原因。@Joop.我已经得到了hextump,但无法理解您的语句“知道字节/位,就可以很容易地看出这是否确实是非法的UTF-8”。你能解释一下吗。我对编码和十六进制结构非常陌生。我添加了一个dumpBytes,这样我们可以看到有问题的数据。得到十六进制转储,可以找到问题区域,谢谢你提供的信息