BATCH-1224: added appendAllowed flag to FlatFileItemwWriter

This commit is contained in:
Dave Syer
2010-11-18 12:08:22 +00:00
parent acf234a849
commit 01f91f166b
2 changed files with 108 additions and 8 deletions

View File

@@ -18,6 +18,7 @@ package org.springframework.batch.item.file;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.Writer;
@@ -26,6 +27,7 @@ import java.nio.channels.FileChannel;
import java.nio.charset.UnsupportedCharsetException;
import java.util.List;
import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.batch.item.ExecutionContext;
@@ -88,9 +90,11 @@ public class FlatFileItemWriter<T> extends ExecutionContextUserSupport implement
private FlatFileFooterCallback footerCallback;
private String lineSeparator = DEFAULT_LINE_SEPARATOR;
private boolean transactional = DEFAULT_TRANSACTIONAL;
private boolean append = false;
public FlatFileItemWriter() {
setName(ClassUtils.getShortName(FlatFileItemWriter.class));
}
@@ -102,6 +106,9 @@ public class FlatFileItemWriter<T> extends ExecutionContextUserSupport implement
*/
public void afterPropertiesSet() throws Exception {
Assert.notNull(lineAggregator, "A LineAggregator must be provided.");
if (append) {
shouldDeleteIfExists = false;
}
}
/**
@@ -141,9 +148,10 @@ public class FlatFileItemWriter<T> extends ExecutionContextUserSupport implement
/**
* Flag to indicate that the target file should be deleted if it already
* exists, otherwise it will be appended. If headers are emitted then
* appending will cause them to show up in the middle of the file. Defaults
* to true (so no appending except on restart).
* exists, otherwise it will be created. Defaults to true, so no appending
* except on restart. If set to false and {@link #setAppendAllowed(boolean)
* appendAllowed} is also false then there will be an exception when the
* stream is opened to prevent existing data being potentially corrupted.
*
* @param shouldDeleteIfExists the flag value to set
*/
@@ -151,6 +159,20 @@ public class FlatFileItemWriter<T> extends ExecutionContextUserSupport implement
this.shouldDeleteIfExists = shouldDeleteIfExists;
}
/**
* Flag to indicate that the target file should be appended if it already
* exists. If this flag is set then the flag
* {@link #setShouldDeleteIfExists(boolean) shouldDeleteIfExists} is
* automatically set to false, so that flag should not be set explicitly.
* Defaults value is false.
*
* @param append the flag value to set
*/
public void setAppendAllowed(boolean append) {
this.append = append;
this.shouldDeleteIfExists = false;
}
/**
* Flag to indicate that the target file should be deleted if no lines have
* been written (other than header and footer) on close. Defaults to false.
@@ -292,7 +314,7 @@ public class FlatFileItemWriter<T> extends ExecutionContextUserSupport implement
catch (IOException ioe) {
throw new ItemStreamException("Failed to initialize writer", ioe);
}
if (outputState.lastMarkedByteOffsetPosition == 0) {
if (outputState.lastMarkedByteOffsetPosition == 0 && !outputState.appending) {
if (headerCallback != null) {
try {
headerCallback.writeHeader(outputState.outputBufferedWriter);
@@ -341,6 +363,7 @@ public class FlatFileItemWriter<T> extends ExecutionContextUserSupport implement
Assert.state(!file.exists() || file.canWrite(), "Resource is not writable: [" + resource + "]");
state = new OutputState();
state.setDeleteIfExists(shouldDeleteIfExists);
state.setAppendAllowed(append);
state.setEncoding(encoding);
}
return (OutputState) state;
@@ -375,6 +398,10 @@ public class FlatFileItemWriter<T> extends ExecutionContextUserSupport implement
boolean initialized = false;
private boolean append = false;
private boolean appending = false;
/**
* Return the byte offset position of the cursor in the output file as a
* long integer.
@@ -396,6 +423,13 @@ public class FlatFileItemWriter<T> extends ExecutionContextUserSupport implement
}
/**
* @param append
*/
public void setAppendAllowed(boolean append) {
this.append = append;
}
/**
* @param executionContext
*/
@@ -492,13 +526,28 @@ public class FlatFileItemWriter<T> extends ExecutionContextUserSupport implement
private void initializeBufferedWriter() throws IOException {
File file = resource.getFile();
if (file.exists() && append) {
FileInputStream input = new FileInputStream(file);
System.err.println(IOUtils.toString(input));
System.err.println(input.getChannel().position());
}
FileUtils.setUpOutputFile(file, restarted, shouldDeleteIfExists);
FileUtils.setUpOutputFile(file, restarted || append, shouldDeleteIfExists);
os = new FileOutputStream(file.getAbsolutePath(), true);
fileChannel = os.getChannel();
outputBufferedWriter = getBufferedWriter(fileChannel, encoding);
outputBufferedWriter.flush();
if (append) {
// Bug in IO library? This doesn't work...
// lastMarkedByteOffsetPosition = fileChannel.position();
if (file.length() > 0) {
appending = true;
// Don't write the headers again
}
}
Assert.state(outputBufferedWriter != null);
// in case of restarting reset position to last committed point
@@ -528,7 +577,8 @@ public class FlatFileItemWriter<T> extends ExecutionContextUserSupport implement
closeStream();
}
});
} else {
}
else {
return new BufferedWriter(writer);
}
}