[英]Opening a file in append mode but truncating the file if not empty in JAVA 11
如果它不存在,我想创建一个 result.csv 文件,然后我多次调用write
并通过调用附加相应的消息。
但是如果文件在程序运行之前已经存在并且包含一些东西,我想删除它的内容,然后开始附加相应的消息。
我尝试了以下方法:
public final class Writer {
public static void write(String message, String destinationPath) {
try (FileWriter fw = new FileWriter(destinationPath, true);
BufferedWriter bw = new BufferedWriter(fw)
) {
bw.write(message);
bw.newLine();
} catch (IOException e) {
e.printStackTrace();
}
}
}
但是,正如您可能猜到的那样,当我一遍又一遍地运行程序时,它只是在现有行上添加新行,而不是在程序运行之前擦除里面的内容。
write
的调用是这样完成的:
studentNamesAndIds.values().forEach(id -> Writer.write(id+","+ DecideGrade.softLookUp(id, studentIdsAndGrades),writeFilePath));
我应该改变什么才能得到我一开始提到的结果?
PS 如果我在没有第二个参数的情况下声明new FileWriter(destinationPath)
为true
,那么每次调用write
都会删除我文件的内容,我会删除里面的最后一行。
这段代码应该根据您对问题的描述来完成这项工作:
public final class Writer
{
private static final Set<String> m_AppendMarkers = new HashMap<>();
public static void write( final String message, final String destinationPath )
{
final var append = m_AppendMarkers.contains( destinationPath );
try( final var fw = new FileWriter( destinationPath, append );
final var bw = new BufferedWriter( fw ) )
{
bw.write( message );
bw.newLine();
m_AppendMarkers.add( destinationPath );
}
catch( final IOException e )
{
e.printStackTrace();
}
}
}
每次重新启动程序时,集合都是空的,因此Set::contains
将在第一次尝试写入给定文件时返回false
; 为了进一步尝试,文件的路径已添加到集合中,包含检查将为您提供true
,因此将附加更多行。
但老实说,虽然这可行,但您应该考虑不同的设计! 因此,为您写入的每一行新行打开和关闭文件并不是一个好主意。
使用静态方法也不是好的设计(这就是为什么需要Set
而不是简单的boolean
标志的原因)。
要做到正确(或至少更好一点)试试这个:
public class YourProgram
{
private static class Writer implements AutoClosable
{
private final String m_DestinationPath;
private final StringJoiner m_Buffer ) = new StringJoiner( "\n", "", "\n" );
public Writer( final String destinationPath )
{
m_DestinationPath = destinationPath;
}
@Overwrite
public final void close() throws IOException
{
try( final var writer = new BufferedWriter( new FileWriter( m_DestinationPath, false ) ) )
{
writer.write( m_Buffer.toString() );
}
}
public static void write( final String message )
{
m_Buffer.add( message );
}
}
// class Writer
private static Writer m_Writer;
public static final void main( final String... args )
{
try( var w = new Writer( "TheNameOfYourOutputFile" ) )
{
m_Writer = w;
// Your code goes here …
…
}
catch( final IOException e )
{
err.println( "Failed to write the output file" );
e.printStackTrace( err );
}
catch( final Throwable t )
{
err.println( "Unhandled exception" );
t.printStackTrace( err );
}
}
}
// class YourProgram
省略了错误处理以保持可读性。
只要您不尝试写入几千兆字节的数据,这应该比其他设计更顺畅。 好的,它不是崩溃保存,如果程序将被外部终止,则不会将任何内容写入输出文件。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.