1 /*
2 * Copyright 2013 University of Glasgow.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 package broadwick.io;
17
18 import broadwick.BroadwickVersion;
19 import com.google.common.base.Throwables;
20 import java.io.BufferedOutputStream;
21 import java.io.FileOutputStream;
22 import java.io.IOException;
23 import lombok.extern.slf4j.Slf4j;
24
25 /**
26 * Simple interface to printing values to a file. It simply wraps the java io classes to simplify the output of data.
27 */
28 @Slf4j
29 public class FileOutput implements AutoCloseable {
30
31 /**
32 * Create a null file output object similar to writing to /dev/null. This allows for empty FileOutput objects to be
33 * used without throwing NullPointerExceptions.
34 */
35 public FileOutput() {
36 buffer = new NullOutputStream();
37 }
38
39 /**
40 * Create a file with the given name.
41 * @param dataFileName the name of the file.
42 */
43 public FileOutput(final String dataFileName) {
44 this(dataFileName, false, false, DEFAULT_ENCODING);
45 }
46
47 /**
48 * Create a file with the given name.
49 * @param dataFileName the name of the file.
50 * @param addVersion boolean that determines whether or not the project version number should be applied to the
51 * start of the file.
52 */
53 public FileOutput(final String dataFileName, final boolean addVersion) {
54 this(dataFileName, addVersion, true, DEFAULT_ENCODING);
55 }
56
57 /**
58 * Create a file with the given name.
59 * @param dataFileName the name of the file.
60 * @param addVersion boolean that determines whether or not the project version number should be applied to the
61 * start of the file.
62 * @param append if <code>true</code>, then bytes will be written to the end of the file.
63 */
64 public FileOutput(final String dataFileName, final boolean addVersion, final boolean append) {
65 this(dataFileName, addVersion, append, DEFAULT_ENCODING);
66 }
67
68 /**
69 * Create a file with the given name.
70 * @param dataFileName the name of the file.
71 * @param addVersion boolean that determines whether or not the project version number should be applied to the
72 * start of the file.
73 * @param append if <code>true</code>, then bytes will be written to the end of the file.
74 * @param encoding the character encoding used in the file.
75 */
76 public FileOutput(final String dataFileName, final boolean addVersion, final boolean append,
77 final String encoding) {
78 try {
79 fileEncoding = encoding;
80 buffer = new BufferedOutputStream(new FileOutputStream(dataFileName, append));
81 if (addVersion) {
82 buffer.write("# Version : ".getBytes(fileEncoding));
83 buffer.write(BroadwickVersion.getVersionAndTimeStamp().getBytes(fileEncoding));
84 buffer.write("\n".getBytes(fileEncoding));
85 buffer.flush();
86 }
87 } catch (IOException ex) {
88 log.error(ex.getLocalizedMessage());
89 throw new BroadwickIOException(ex.getLocalizedMessage() + Throwables.getStackTraceAsString(ex));
90 }
91 }
92
93 /**
94 * Write the string to the file stream.
95 * @param str the string to write to the stream.
96 */
97 public final void write(final String str) {
98 try {
99 buffer.write(str.getBytes(fileEncoding));
100 buffer.flush();
101 } catch (IOException ex) {
102 log.error(ex.getLocalizedMessage());
103 throw new BroadwickIOException(ex.getLocalizedMessage() + Throwables.getStackTraceAsString(ex));
104 }
105 }
106
107 /**
108 * Writes a formatted string to the file stream.
109 * @param format A format string as described in <a href="#syntax">Format string syntax</a>
110 * @param args Arguments referenced by the format specifiers in the format string. If there are more arguments
111 * than format specifiers, the extra arguments are ignored. The maximum number of arguments is limited
112 * by the maximum dimension of a Java array as defined by the <a
113 * href="http://java.sun.com/docs/books/vmspec/">Java Virtual Machine Specification</a>
114 * @return the string written to the buffer.
115 */
116 public final String write(final String format, final Object... args) {
117 String str = "";
118 try {
119 str = String.format(format, args);
120 buffer.write(str.getBytes(fileEncoding));
121 buffer.flush();
122 } catch (IOException ex) {
123 log.error(ex.getLocalizedMessage());
124 throw new BroadwickIOException(ex.getLocalizedMessage() + Throwables.getStackTraceAsString(ex));
125 }
126 return str;
127 }
128
129 @Override
130 public final void close() {
131 try {
132 buffer.close();
133 } catch (IOException ex) {
134 log.error(ex.getLocalizedMessage());
135 }
136 }
137
138 /**
139 * Flushes the file stream.
140 */
141 public final void flush() {
142 try {
143 buffer.flush();
144 } catch (IOException ex) {
145 log.error(ex.getLocalizedMessage());
146 }
147 }
148
149 /**
150 * Save data in the form of a string to a named file.
151 * @param dataFileName the name of the file in which the data is to be saved.
152 * @param data the data to be saved.
153 * @param addVersion add the project version number to the start of the file.
154 */
155 public static void saveToFile(final String dataFileName, final String data, final boolean addVersion) {
156 try (FileOutput fl = new FileOutput(dataFileName, addVersion)) {
157 fl.write(data);
158 // we can let any thrown BroadIOException get caught further up the stack.
159 }
160 }
161
162 /**
163 * Save data in the form of a string to a named file.
164 * @param dataFileName the name of the file in which the data is to be saved.
165 * @param format A format string as described in <a href="#syntax">Format string syntax</a>
166 * @param addVersion add the project version number to the start of the file.
167 * @param args Arguments referenced by the format specifiers in the format string. If there are more
168 * arguments than format specifiers, the extra arguments are ignored. The maximum number of
169 * arguments is limited by the maximum dimension of a Java array as defined by the <a
170 * href="http://java.sun.com/docs/books/vmspec/">Java Virtual Machine Specification</a>
171 */
172 public static void saveToFile(final String dataFileName, final String format, final boolean addVersion, final Object... args) {
173 try (FileOutput fl = new FileOutput(dataFileName, addVersion)) {
174 fl.write(format, args);
175 // we can let any thrown BroadIOException get caught further up the stack.
176 }
177 }
178
179 private BufferedOutputStream buffer;
180 private String fileEncoding;
181 private static final String DEFAULT_ENCODING = "UTF-8";
182
183 }