Skip to content

Commit a9e94d3

Browse files
authored
Merge pull request #475 from metafacture/appendIfFileExistsInObjectFileWriter
Optionally let `ObjectFileWriter` append to existing file instead of overwriting.
2 parents 6e955f7 + 2a993b0 commit a9e94d3

File tree

3 files changed

+78
-32
lines changed

3 files changed

+78
-32
lines changed

metafacture-io/src/main/java/org/metafacture/io/ObjectFileWriter.java

Lines changed: 37 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,8 @@ public final class ObjectFileWriter<T> extends AbstractObjectWriter<T> {
4646
private String path;
4747
private int count;
4848
private Writer writer;
49-
private boolean firstObject;
49+
private boolean appendIfFileExists;
50+
private boolean firstObject = true;
5051
private boolean closed;
5152

5253
private String encoding = "UTF-8";
@@ -59,12 +60,6 @@ public final class ObjectFileWriter<T> extends AbstractObjectWriter<T> {
5960
*/
6061
public ObjectFileWriter(final String path) {
6162
this.path = path;
62-
startNewFile();
63-
64-
final Matcher matcher = VAR_PATTERN.matcher(this.path);
65-
if (!matcher.find()) {
66-
this.path = this.path + VAR;
67-
}
6863
}
6964

7065
@Override
@@ -97,13 +92,13 @@ public void process(final T obj) {
9792
assert !closed;
9893
try {
9994
if (firstObject) {
100-
writer.write(getHeader());
95+
getWriter().write(getHeader());
10196
firstObject = false;
10297
}
10398
else {
104-
writer.write(getSeparator());
99+
getWriter().write(getSeparator());
105100
}
106-
writer.write(obj.toString());
101+
getWriter().write(obj.toString());
107102
}
108103
catch (final IOException e) {
109104
throw new MetafactureException(e);
@@ -112,20 +107,7 @@ public void process(final T obj) {
112107

113108
@Override
114109
public void resetStream() {
115-
if (!closed) {
116-
try {
117-
if (!firstObject) {
118-
writer.write(getFooter());
119-
}
120-
writer.close();
121-
}
122-
catch (final IOException e) {
123-
throw new MetafactureException(e);
124-
}
125-
finally {
126-
closed = true;
127-
}
128-
}
110+
closeStream();
129111
startNewFile();
130112
++count;
131113
}
@@ -135,9 +117,9 @@ public void closeStream() {
135117
if (!closed) {
136118
try {
137119
if (!firstObject) {
138-
writer.write(getFooter());
120+
getWriter().write(getFooter());
139121
}
140-
writer.close();
122+
getWriter().close();
141123
}
142124
catch (final IOException e) {
143125
throw new MetafactureException(e);
@@ -148,11 +130,26 @@ public void closeStream() {
148130
}
149131
}
150132

133+
/**
134+
* Controls whether to open files in append mode if they exist.
135+
* <p>
136+
* The default value is {@code false}.
137+
* <p>
138+
* This property can be changed anytime during processing. It becomes
139+
* effective the next time a new output file is opened.
140+
*
141+
* @param appendIfFileExists true if new data should be appended,
142+
* false to overwrite the existing file.
143+
*/
144+
public void setAppendIfFileExists(final boolean appendIfFileExists) {
145+
this.appendIfFileExists = appendIfFileExists;
146+
}
147+
151148
private void startNewFile() {
152149
final Matcher matcher = VAR_PATTERN.matcher(this.path);
153150
final String currentPath = matcher.replaceAll(String.valueOf(count));
154151
try {
155-
final OutputStream file = new FileOutputStream(currentPath);
152+
final OutputStream file = new FileOutputStream(currentPath, appendIfFileExists);
156153
try {
157154
final OutputStream compressor = compression.createCompressor(file, currentPath);
158155
try {
@@ -175,4 +172,17 @@ private void startNewFile() {
175172
}
176173
}
177174

175+
private Writer getWriter() {
176+
if (writer == null) {
177+
startNewFile();
178+
179+
final Matcher matcher = VAR_PATTERN.matcher(this.path);
180+
if (!matcher.find()) {
181+
this.path = this.path + VAR;
182+
}
183+
}
184+
185+
return writer;
186+
}
187+
178188
}

metafacture-io/src/test/java/org/metafacture/io/ObjectFileWriterCompressionTest.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ public final class ObjectFileWriterCompressionTest {
4747
private static final String FILENAME_BZ2 = "compressed.txt.bz2";
4848
private static final String FILENAME_BZIP2 = "compressed.txt.bzip2";
4949
private static final String FILENAME_GZ = "compressed.txt.gz";
50+
private static final String FILENAME_GZ_NOAUTO = "compressed.txt.gz.noauto";
5051
private static final String FILENAME_GZIP = "compressed.txt.gzip";
5152
private static final String FILENAME_XZ = "compressed.txt.xz";
5253

@@ -76,11 +77,13 @@ public static Iterable<Object[]> data() {
7677
{ FILENAME_BZ2, FileCompression.AUTO, MAGIC_BYTES_BZIP2 },
7778
{ FILENAME_BZIP2, FileCompression.AUTO, MAGIC_BYTES_BZIP2 },
7879
{ FILENAME_GZ, FileCompression.AUTO, MAGIC_BYTES_GZIP },
80+
{ FILENAME_GZ_NOAUTO, FileCompression.AUTO, MAGIC_BYTES_NONE },
7981
{ FILENAME_GZIP, FileCompression.AUTO, MAGIC_BYTES_GZIP },
8082
{ FILENAME_XZ, FileCompression.AUTO, MAGIC_BYTES_XZ },
8183
{ FILENAME_NONE, FileCompression.NONE, MAGIC_BYTES_NONE },
8284
{ FILENAME_BZ2, FileCompression.BZIP2, MAGIC_BYTES_BZIP2 },
8385
{ FILENAME_GZ, FileCompression.GZIP, MAGIC_BYTES_GZIP },
86+
{ FILENAME_GZ_NOAUTO, FileCompression.GZIP, MAGIC_BYTES_GZIP },
8487
{ FILENAME_XZ, FileCompression.XZ, MAGIC_BYTES_XZ },
8588
});
8689
}

metafacture-io/src/test/java/org/metafacture/io/ObjectFileWriterTest.java

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -53,21 +53,44 @@ public final class ObjectFileWriterTest
5353
@Before
5454
public void setup() throws IOException {
5555
file = tempFolder.newFile();
56-
writer = new ObjectFileWriter<String>(file.getAbsolutePath());
56+
setWriter();
5757
}
5858

5959
@Test
6060
public void shouldWriteUTF8EncodedOutput() throws IOException {
6161
assumeFalse("Default encoding is UTF-8: It is not possible to test whether " +
62-
"ObjectFileWriter sets the encoding to UTF-8 correctly.",
62+
"ObjectFileWriter sets the encoding to UTF-8 correctly.",
6363
StandardCharsets.UTF_8.equals(Charset.defaultCharset()));
6464

6565
writer.process(DATA);
6666
writer.closeStream();
6767

68-
final byte[] bytesWritten = Files.readAllBytes(file.toPath());
69-
assertArrayEquals((DATA + "\n").getBytes(StandardCharsets.UTF_8),
70-
bytesWritten); // FileObjectWriter appends new lines
68+
assertOutput(DATA + "\n");
69+
}
70+
71+
@Test
72+
public void shouldOverwriteExistingFileByDefault() throws IOException {
73+
writer.process(DATA);
74+
writer.closeStream();
75+
76+
setWriter();
77+
writer.process(DATA);
78+
writer.closeStream();
79+
80+
assertOutput(DATA + "\n");
81+
}
82+
83+
@Test
84+
public void shouldAppendToExistingFile() throws IOException {
85+
writer.process(DATA);
86+
writer.closeStream();
87+
88+
setWriter();
89+
writer.setAppendIfFileExists(true);
90+
writer.process(DATA);
91+
writer.closeStream();
92+
93+
assertOutput(DATA + "\n" + DATA + "\n");
7194
}
7295

7396
@Override
@@ -83,4 +106,14 @@ protected String getOutput() throws IOException {
83106
}
84107
}
85108

109+
private void setWriter() {
110+
writer = new ObjectFileWriter<String>(file.getAbsolutePath());
111+
}
112+
113+
private void assertOutput(final String expected) throws IOException {
114+
final byte[] bytesWritten = Files.readAllBytes(file.toPath());
115+
assertArrayEquals(expected.getBytes(StandardCharsets.UTF_8),
116+
bytesWritten); // FileObjectWriter appends new lines
117+
}
118+
86119
}

0 commit comments

Comments
 (0)