Java FileWriter在文件末尾写入额外的空值
对于大字符串(60MB或更长),Java FileWriter在文件末尾写入额外的空值,java,string,file-io,filewriter,Java,String,File Io,Filewriter,对于大字符串(60MB或更长),FileWriter会在我的文件末尾附加额外的nulls。对于小字符串,此代码按预期工作 为清楚起见,dat和filePath是字符串 FileWriter fstream = new FileWriter( filePath ); fstream.write( dat ); fstream.close(); File f = new File( filePath ); System.out.println("Data: " + dat.len
FileWriter
会在我的文件末尾附加额外的null
s。对于小字符串,此代码按预期工作
为清楚起见,dat和filePath是字符串
FileWriter fstream = new FileWriter( filePath );
fstream.write( dat );
fstream.close();
File f = new File( filePath );
System.out.println("Data: " + dat.length() + ", File: " + f.length());
简而言之,在什么情况下,两个打印值应该不同
以下是我的示例输出:
Data: 63833144, File: 63833728
由于某种原因,我在文件末尾额外获得了584个null
s。我觉得字符串可能被过度分配是合理的,但这些不应该打印到文件中,对吗?更糟糕的是,如果我明确给出长度:
fstream.write(dat, 0, dat.length());
行为是一样的。巧合的是,如果我说(dat.length()-584),它会做我想做的事情,但只有在这个特定的情况下
有什么想法吗
JDK版本:1.7.0_02
编辑:添加变量的文件类型(两个字符串)我建议您不要使用FileWriter,因为它在您的平台上使用默认编码将字符串转换为字节流 相反,您应该这样做:
Writer writer =
new OutputStreamWriter(
new FileOutputStream( fileName ),
// Always specify encoding compatible with your string
"UTF-8"
);
try
{
writer.write( dat );
writer.flush( );
}
finally
{
writer.close( );
}
此外,字符串长度和结果字节流长度不必匹配。它们将只匹配ASCII文本字符串。什么是“dat”?如果“dat”是StringBuffer,则需要小心。如果StringBuffer的长度大于其内容,则会在末尾追加null。您可以尝试使用dat.toString()。我相信,在转换过程中,空字符将被删除。因此,请使用63833144长字符串运行一个测试,该字符串中只有'a',输出为: 数据:63833144,文件:63833144 所以我确信问题是编码问题
(我会将此作为评论发布,但因为我没有50个代表,所以我无法:/)文件长度取决于编码。这个测试
System.out.println(dat.getBytes().length);
编码后将以字节为单位显示长度,因为
字符串。getBytes
将使用与新FileWriter(文件)
相同的编码(默认值)dat
是字符串,对吗?您的字符串
是否包含任何特殊字符?您知道您正在比较以字符为单位的字符串的长度与以字节为单位的文件长度吗?不一定相同。@TomaszNurkiewicz我知道没有任何Unicode编码会在编码字符串的末尾附加584个无关的空值。是dat
achar[]
array吗?dat和filePath都是Strings@TomaszNurkiewiczdat是一个字符串,在本例中应该是HTML文件的内容。您是正确的,dat.length()与dat.getBytes().length()不匹配。事实上,它与filesize值匹配,所以您是说FileWriter.write()不应该输出字符串的内容,而是它的内部表示形式?我试图将其转换为charArray,但遇到了同样的问题。实现这一点的正确方法是什么?关于编码的一般性建议很好,但不能解释OP看到的行为。@millimoose。OP提供的信息非常有限,很难继续下去。dat
aString
还是char[]
?dat
ASCII还是非ASCII?等。@AlexanderPogrebnyak尽管如此,他提供的信息似乎排除了这种编码相关错误导致的长度差异。当提供的信息不足时,要做的是请求更多的信息,而不是给出“错误”(即问题)的答案。您是否有任何关于此行为的参考资料(如错误报告)?因为在这种情况下,StringBuffer
(或StringBuilder
)的行为应该与任何其他CharSequence
类似。请检查Javadoc的setLength()方法。它确实提供了一些关于StringBuffer在幕后如何处理长度和空值的指示。它是一个字符串,但我确实注意到.getBytes()。该字符串的长度比.length()长584,因此与我上面输出的值匹配。我不知道在60MB的文件中会发生584次什么,它可以是“空”字符。字符(0)空字符和终止符在字符串或文件的上下文中完全有效。在C语言中,经常使用空终止符。我不确定字符串是如何从文件中读取的,但我认为修剪和/或检测null(并忽略它们)在这里可能很重要。我想我的问题是,那么,什么是正确的方式来输出字符串的字符串内容呢?我同意这可能是一个编码问题,我想我只是不确定如何修复它。我甚至试着按照下面的建议制作UTF-8编写器,但也遇到了同样的问题。@ChadMourning Hm如果这样做有效,这并不能解释问题,但PrintStream print=new PrintStream(new FileOutputStream(“test.txt”);打印。打印;是的,字符串中有584个字符是多字节字符,这就解释了大小的差异。输出中的实际错误是因为读入这些字符的方式将所有多字节字符压缩为单个字节,在末尾留下额外的\0。