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 }