Skip to content

Commit

Permalink
Merge pull request #475 from metafacture/appendIfFileExistsInObjectFi…
Browse files Browse the repository at this point in the history
…leWriter

Optionally let `ObjectFileWriter` append to existing file instead of overwriting.
  • Loading branch information
blackwinter authored Nov 18, 2022
2 parents 6e955f7 + 2a993b0 commit a9e94d3
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 32 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ public final class ObjectFileWriter<T> extends AbstractObjectWriter<T> {
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";
Expand All @@ -59,12 +60,6 @@ public final class ObjectFileWriter<T> extends AbstractObjectWriter<T> {
*/
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
Expand Down Expand Up @@ -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);
Expand All @@ -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;
}
Expand All @@ -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);
Expand All @@ -148,11 +130,26 @@ public void closeStream() {
}
}

/**
* Controls whether to open files in append mode if they exist.
* <p>
* The default value is {@code false}.
* <p>
* 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 {
Expand All @@ -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;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -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";

Expand Down Expand Up @@ -76,11 +77,13 @@ public static Iterable<Object[]> 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 },
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,21 +53,44 @@ public final class ObjectFileWriterTest
@Before
public void setup() throws IOException {
file = tempFolder.newFile();
writer = new ObjectFileWriter<String>(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
Expand All @@ -83,4 +106,14 @@ protected String getOutput() throws IOException {
}
}

private void setWriter() {
writer = new ObjectFileWriter<String>(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
}

}

0 comments on commit a9e94d3

Please sign in to comment.