Java―;读取、处理和写入UTF-8文件

Java―;读取、处理和写入UTF-8文件,java,encoding,utf-8,io,copy,Java,Encoding,Utf 8,Io,Copy,我试图编写一些程序,读取可能有编码错误的UTF-8编码文件,处理内容,并将结果写入同样以UTF-8编码的输出文件 我的程序应该修改内容(搜索和替换),并将其余的内容一一复制。换句话说:如果要搜索的项等于要替换的项,则输入和输出文件也应相等 我通常使用以下代码: in = Paths.get( <filename1> ); out = Paths.get( <filename2> ); Files.deleteIfExists( out ); Files.createFi

我试图编写一些程序,读取可能有编码错误的UTF-8编码文件,处理内容,并将结果写入同样以UTF-8编码的输出文件

我的程序应该修改内容(搜索和替换),并将其余的内容一一复制。换句话说:如果要搜索的项等于要替换的项,则输入和输出文件也应相等

我通常使用以下代码:

in = Paths.get( <filename1> );
out = Paths.get( <filename2> );

Files.deleteIfExists( out );
Files.createFile( out );

CharsetDecoder decoder = StandardCharsets.UTF_8.newDecoder();
decoder.onMalformedInput( CodingErrorAction.IGNORE );
decoder.onUnmappableCharacter( CodingErrorAction.IGNORE );

BufferedReader reader = new BufferedReader( 
    new InputStreamReader(
        new FileInputStream( this.in.toFile() ), decoder ) );

CharsetEncoder encoder = StandardCharsets.UTF_8.newEncoder();
encoder.onMalformedInput( CodingErrorAction.IGNORE );
encoder.onUnmappableCharacter( CodingErrorAction.IGNORE );

BufferedWriter writer = new BufferedWriter( 
    new OutputStreamWriter(
        new FileOutputStream( this.out.toFile() ), encoder) );

char[] charBuffer = new char[100];
int readCharCount;
StringBuffer buffer = new StringBuffer();

while( ( readCharCount = reader.read( charBuffer ) ) > 0 )
{
    buffer.append( charBuffer, 0, readCharCount );
    //here goes more code to process the content
    //buffer must be written to output on each iteration
}

writer.write( buffer.toString() );
reader.close();
writer.close();
in=path.get();
out=path.get();
文件。deleteIfExists(out);
createFile(out);
CharsetDecoder decoder=StandardCharsets.UTF_8.newDecoder();
解码器.onMalformedInput(CodingErrorAction.IGNORE);
解码器.onUnmappableCharacter(CodingErrorAction.IGNORE);
BufferedReader reader=新的BufferedReader(
新的InputStreamReader(
新文件输入流(this.in.toFile()),解码器);
CharsetEncoder编码器=StandardCharsets.UTF_8.newEncoder();
编码器.onMalformedInput(CodingErrorAction.IGNORE);
编码器.onUnmappableCharacter(CodingErrorAction.IGNORE);
BufferedWriter=新的BufferedWriter(
新的OutputStreamWriter(
新的FileOutputStream(this.out.toFile()),编码器);
char[]charBuffer=新字符[100];
int readCharCount;
StringBuffer=新的StringBuffer();
而((readCharCount=reader.read(charBuffer))>0)
{
append(charBuffer,0,readCharCount);
//下面是处理内容的更多代码
//每次迭代时,必须将缓冲区写入输出
}
writer.write(buffer.toString());
reader.close();
writer.close();
但这是行不通的。为了比较文件,我做了一个小JUnit测试,但失败了:

byte[] bytesf1 = Files.readAllBytes( Paths.get( <filename1> ) );
byte[] bytesf2 = Files.readAllBytes( Paths.get( <filename2> ) );
assertTrue( bytesf1.equals( bytesf2 ) ); 
byte[]bytesf1=Files.readAllBytes(path.get());
byte[]bytesf2=Files.readAllBytes(path.get());
assertTrue(bytesf1.equals(bytesf2));
我做错了什么,或者我能做些什么来让它工作

提前谢谢你, 菲利普

编辑

除非我能在确保输入文件以UTF-8编码后使测试工作正常,否则基本错误是什么,我真正感兴趣的问题是:


上述方法是否保证UTF-8文件中的缺陷也被一一复制,或者将字符加载到
Stringbuffer
的过程是否改变了这一点

Java数组不实现基于值的
等于
。这将永远失败:

assertTrue( bytesf1.equals( bytesf2 ) ); 
考虑:

assertArrayEquals(bytesf1, bytesf2);


您的文件是否包含字节顺序标记(BOM)?好问题!我怎么才能知道呢?结果似乎完全相同,只是有些字符不同……您可以在测试用例中使用array.equals(bytesf1,bytesf2)而不是bytesf1。equals(bytesf2)我可以,但测试仍然失败……grep-rl$'\xEF\xBB\xBF'-->没有匹配,所以我猜没有BOM
assertTrue(Arrays.equals(bytesf1, bytesf2));