diff --git a/metafacture-io/src/main/java/org/metafacture/io/ObjectFileWriter.java b/metafacture-io/src/main/java/org/metafacture/io/ObjectFileWriter.java index bcbf90fb3..edbcc72f0 100644 --- a/metafacture-io/src/main/java/org/metafacture/io/ObjectFileWriter.java +++ b/metafacture-io/src/main/java/org/metafacture/io/ObjectFileWriter.java @@ -46,7 +46,8 @@ public final class ObjectFileWriter extends AbstractObjectWriter { private String path; private int count; private Writer writer; - private boolean firstObject; + private boolean appendIfFileExists; + private boolean firstObject = true; private boolean closed; private String encoding = "UTF-8"; @@ -59,12 +60,6 @@ public final class ObjectFileWriter extends AbstractObjectWriter { */ public ObjectFileWriter(final String path) { this.path = path; - startNewFile(); - - final Matcher matcher = VAR_PATTERN.matcher(this.path); - if (!matcher.find()) { - this.path = this.path + VAR; - } } @Override @@ -97,13 +92,13 @@ public void process(final T obj) { assert !closed; try { if (firstObject) { - writer.write(getHeader()); + getWriter().write(getHeader()); firstObject = false; } else { - writer.write(getSeparator()); + getWriter().write(getSeparator()); } - writer.write(obj.toString()); + getWriter().write(obj.toString()); } catch (final IOException e) { throw new MetafactureException(e); @@ -112,20 +107,7 @@ public void process(final T obj) { @Override public void resetStream() { - if (!closed) { - try { - if (!firstObject) { - writer.write(getFooter()); - } - writer.close(); - } - catch (final IOException e) { - throw new MetafactureException(e); - } - finally { - closed = true; - } - } + closeStream(); startNewFile(); ++count; } @@ -135,9 +117,9 @@ public void closeStream() { if (!closed) { try { if (!firstObject) { - writer.write(getFooter()); + getWriter().write(getFooter()); } - writer.close(); + getWriter().close(); } catch (final IOException e) { throw new MetafactureException(e); @@ -148,11 +130,26 @@ public void closeStream() { } } + /** + * Controls whether to open files in append mode if they exist. + *

+ * The default value is {@code false}. + *

+ * This property can be changed anytime during processing. It becomes + * effective the next time a new output file is opened. + * + * @param appendIfFileExists true if new data should be appended, + * false to overwrite the existing file. + */ + public void setAppendIfFileExists(final boolean appendIfFileExists) { + this.appendIfFileExists = appendIfFileExists; + } + private void startNewFile() { final Matcher matcher = VAR_PATTERN.matcher(this.path); final String currentPath = matcher.replaceAll(String.valueOf(count)); try { - final OutputStream file = new FileOutputStream(currentPath); + final OutputStream file = new FileOutputStream(currentPath, appendIfFileExists); try { final OutputStream compressor = compression.createCompressor(file, currentPath); try { @@ -175,4 +172,17 @@ private void startNewFile() { } } + private Writer getWriter() { + if (writer == null) { + startNewFile(); + + final Matcher matcher = VAR_PATTERN.matcher(this.path); + if (!matcher.find()) { + this.path = this.path + VAR; + } + } + + return writer; + } + } diff --git a/metafacture-io/src/test/java/org/metafacture/io/ObjectFileWriterCompressionTest.java b/metafacture-io/src/test/java/org/metafacture/io/ObjectFileWriterCompressionTest.java index 4d810d35c..6ed9580df 100644 --- a/metafacture-io/src/test/java/org/metafacture/io/ObjectFileWriterCompressionTest.java +++ b/metafacture-io/src/test/java/org/metafacture/io/ObjectFileWriterCompressionTest.java @@ -47,6 +47,7 @@ public final class ObjectFileWriterCompressionTest { private static final String FILENAME_BZ2 = "compressed.txt.bz2"; private static final String FILENAME_BZIP2 = "compressed.txt.bzip2"; private static final String FILENAME_GZ = "compressed.txt.gz"; + private static final String FILENAME_GZ_NOAUTO = "compressed.txt.gz.noauto"; private static final String FILENAME_GZIP = "compressed.txt.gzip"; private static final String FILENAME_XZ = "compressed.txt.xz"; @@ -76,11 +77,13 @@ public static Iterable data() { { FILENAME_BZ2, FileCompression.AUTO, MAGIC_BYTES_BZIP2 }, { FILENAME_BZIP2, FileCompression.AUTO, MAGIC_BYTES_BZIP2 }, { FILENAME_GZ, FileCompression.AUTO, MAGIC_BYTES_GZIP }, + { FILENAME_GZ_NOAUTO, FileCompression.AUTO, MAGIC_BYTES_NONE }, { FILENAME_GZIP, FileCompression.AUTO, MAGIC_BYTES_GZIP }, { FILENAME_XZ, FileCompression.AUTO, MAGIC_BYTES_XZ }, { FILENAME_NONE, FileCompression.NONE, MAGIC_BYTES_NONE }, { FILENAME_BZ2, FileCompression.BZIP2, MAGIC_BYTES_BZIP2 }, { FILENAME_GZ, FileCompression.GZIP, MAGIC_BYTES_GZIP }, + { FILENAME_GZ_NOAUTO, FileCompression.GZIP, MAGIC_BYTES_GZIP }, { FILENAME_XZ, FileCompression.XZ, MAGIC_BYTES_XZ }, }); } diff --git a/metafacture-io/src/test/java/org/metafacture/io/ObjectFileWriterTest.java b/metafacture-io/src/test/java/org/metafacture/io/ObjectFileWriterTest.java index 6842cd7aa..213ba6aec 100644 --- a/metafacture-io/src/test/java/org/metafacture/io/ObjectFileWriterTest.java +++ b/metafacture-io/src/test/java/org/metafacture/io/ObjectFileWriterTest.java @@ -53,21 +53,44 @@ public final class ObjectFileWriterTest @Before public void setup() throws IOException { file = tempFolder.newFile(); - writer = new ObjectFileWriter(file.getAbsolutePath()); + setWriter(); } @Test public void shouldWriteUTF8EncodedOutput() throws IOException { assumeFalse("Default encoding is UTF-8: It is not possible to test whether " + - "ObjectFileWriter sets the encoding to UTF-8 correctly.", + "ObjectFileWriter sets the encoding to UTF-8 correctly.", StandardCharsets.UTF_8.equals(Charset.defaultCharset())); writer.process(DATA); writer.closeStream(); - final byte[] bytesWritten = Files.readAllBytes(file.toPath()); - assertArrayEquals((DATA + "\n").getBytes(StandardCharsets.UTF_8), - bytesWritten); // FileObjectWriter appends new lines + assertOutput(DATA + "\n"); + } + + @Test + public void shouldOverwriteExistingFileByDefault() throws IOException { + writer.process(DATA); + writer.closeStream(); + + setWriter(); + writer.process(DATA); + writer.closeStream(); + + assertOutput(DATA + "\n"); + } + + @Test + public void shouldAppendToExistingFile() throws IOException { + writer.process(DATA); + writer.closeStream(); + + setWriter(); + writer.setAppendIfFileExists(true); + writer.process(DATA); + writer.closeStream(); + + assertOutput(DATA + "\n" + DATA + "\n"); } @Override @@ -83,4 +106,14 @@ protected String getOutput() throws IOException { } } + private void setWriter() { + writer = new ObjectFileWriter(file.getAbsolutePath()); + } + + private void assertOutput(final String expected) throws IOException { + final byte[] bytesWritten = Files.readAllBytes(file.toPath()); + assertArrayEquals(expected.getBytes(StandardCharsets.UTF_8), + bytesWritten); // FileObjectWriter appends new lines + } + }