1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package no.sintef.file;
22
23 import java.awt.Component;
24 import java.io.BufferedInputStream;
25 import java.io.BufferedOutputStream;
26 import java.io.ByteArrayOutputStream;
27 import java.io.File;
28 import java.io.FileInputStream;
29 import java.io.FileNotFoundException;
30 import java.io.FileOutputStream;
31 import java.io.IOException;
32 import java.io.InputStream;
33 import java.net.URL;
34 import java.util.ArrayList;
35 import java.util.Arrays;
36 import java.util.List;
37
38 import javax.swing.JFileChooser;
39 import javax.swing.JOptionPane;
40 import javax.swing.filechooser.FileFilter;
41
42 import org.apache.log4j.Logger;
43
44 /***
45 * IO utility class.
46 *
47 * @author Fredrik Vraalsen
48 */
49 public final class IOUtils {
50
51 private static final Logger LOGGER = Logger.getLogger(IOUtils.class);
52 private static final int BUF_LEN = 4096;
53 private static final int IO_WAIT_LENGTH = 100;
54 private static File currentDir = null;
55
56 /***
57 * Prevent instantiation of utility class.
58 */
59 private IOUtils() {
60 }
61
62 /***
63 * Get current default directory.
64 *
65 * @return current default directory
66 */
67 public static File getDefaultDir() {
68 return currentDir;
69 }
70
71 /***
72 * Set current default directory.
73 *
74 * @param dir new current default directory.
75 */
76 public static void setDefaultDir(File dir) {
77 if (dir == null || dir.isDirectory()) {
78 currentDir = dir;
79 } else {
80 throw new IllegalArgumentException("dir " + dir + " is not directory");
81 }
82 }
83
84 /***
85 * Read complete File contents into byte array.
86 *
87 * @param file
88 * File to read from
89 * @return byte array of File contents
90 * @throws IOException
91 * if IO error occurs
92 */
93 public static byte[] readFully(File file) throws IOException {
94 if (file == null) {
95 throw new IllegalArgumentException("File is null");
96 }
97 if (!file.exists()) {
98 throw new FileNotFoundException("File not found: "
99 + (file != null ? file.getAbsolutePath() : null));
100 }
101 if (!file.isFile() || !file.canRead()) {
102 throw new IOException("Cannot read file: " + file.getAbsolutePath());
103 }
104 byte[] bytes = readFully(new FileInputStream(file));
105 if ((bytes != null) && (bytes.length != file.length())) {
106 throw new IOException("Premature end of file: " + file.getAbsolutePath());
107 }
108 return bytes;
109 }
110
111 /***
112 * Read contents of URL into byte array.
113 *
114 * @param url
115 * URL to read from
116 * @return byte array of URL contents
117 * @throws IOException
118 * if IO error occurs
119 */
120 public static byte[] readFully(URL url) throws IOException {
121 if (url == null) {
122 throw new IllegalArgumentException("URL is null");
123 }
124 return readFully(url.openStream());
125 }
126
127 /***
128 * Read contents of InputStream into byte array.
129 *
130 * @param is
131 * InputStream to read from
132 * @return byte array of InputStream contents
133 * @throws IOException
134 * if IO error occurs
135 */
136 public static byte[] readFully(InputStream is) throws IOException {
137 ByteArrayOutputStream baos = new ByteArrayOutputStream();
138 byte[] buf = new byte[BUF_LEN];
139 BufferedInputStream bis = new BufferedInputStream(is);
140 int read;
141 while ((read = bis.read(buf)) != -1) {
142 baos.write(buf, 0, read);
143 if (read == 0) {
144 LOGGER.debug("Waiting for data...");
145 try {
146
147 Thread.sleep(IO_WAIT_LENGTH);
148 } catch (InterruptedException e) {
149 throw new IOException("Interrupted while waiting for data");
150 }
151 }
152 }
153 return baos.toByteArray();
154 }
155
156 /***
157 * Save contents of byte array to the specified file.
158 *
159 * @param bytes
160 * byte array with contents to save
161 * @param file
162 * file to save to
163 * @throws IOException
164 * if IO error occurs
165 */
166 public static void saveFile(byte[] bytes, File file) throws IOException {
167 if (bytes == null || file == null) {
168 throw new IllegalArgumentException("null argument");
169 }
170 if (file.exists() && !file.canWrite()) {
171 throw new IOException("Unable to write to file: " + file.getAbsolutePath());
172 }
173 BufferedOutputStream bos = null;
174 try {
175 bos = new BufferedOutputStream(new FileOutputStream(file));
176 bos.write(bytes);
177 } finally {
178 if (bos != null) {
179 bos.close();
180 }
181 }
182 }
183
184 /***
185 * Show file dialog requesting user to choose file to save to.
186 *
187 * @param defaultFilename
188 * default file name for dialog
189 * @param parent
190 * parent Component to align the dialog to
191 * @return File to save contents to, or null if cancelled or file not
192 * writable
193 */
194 public static File showSaveDialog(String defaultFilename, Component parent) {
195 while (true) {
196 File result = showFileDialog(defaultFilename, null, parent, JFileChooser.SAVE_DIALOG);
197 if (result == null) {
198 return null;
199 }
200 if (!result.exists()) {
201 return result;
202 }
203 if (!result.canWrite()) {
204 JOptionPane.showMessageDialog(parent,
205 "File already exists and is not writeable",
206 "Save error", JOptionPane.ERROR_MESSAGE);
207
208 } else {
209 int option = JOptionPane.showConfirmDialog(parent,
210 "Overwrite existing file " + result.getName() + "?",
211 "Overwrite file?", JOptionPane.YES_NO_CANCEL_OPTION);
212 if (option == JOptionPane.YES_OPTION) {
213 return result;
214 } else if (option == JOptionPane.CANCEL_OPTION) {
215 return null;
216 }
217 }
218 }
219 }
220
221 /***
222 * Show file dialog to ask user to select a file to open.
223 *
224 * @param defaultFilename
225 * default file name for dialog
226 * @param filters
227 * array of filename filters
228 * @param parent
229 * parent Component to align the dialog to
230 * @return File to open
231 */
232 public static File showOpenDialog(String defaultFilename, FileFilter[] filters, Component parent) {
233 return showFileDialog(defaultFilename, filters, parent, JFileChooser.OPEN_DIALOG);
234 }
235
236 /***
237 * Merge two FileFilter arrays.
238 *
239 * @param f1 the first FileFilter array
240 * @param f2 the second FileFilter array
241 * @return the merged FileFilters
242 */
243 public static FileFilter[] mergeFilters(FileFilter[] f1, FileFilter[] f2) {
244 List result = new ArrayList();
245 if (f1 != null) {
246 result.addAll(Arrays.asList(f1));
247 }
248 if (f2 != null) {
249 result.addAll(Arrays.asList(f2));
250 }
251 return (FileFilter[]) result.toArray(new FileFilter[0]);
252 }
253
254 /***
255 * Show file dialog to ask user to select a file to open or save.
256 *
257 * @param defaultFilename
258 * default file name for dialog
259 * @param filters
260 * array of filename filters
261 * @param parent
262 * parent Component to align the dialog to
263 * @param type
264 * JFileChooser.OPEN_DIALOG or JFileChooser.SAVE_DIALOG
265 * @return File to open or save
266 */
267 private static File showFileDialog(String defaultFilename, FileFilter[] filters, Component parent, int type) {
268 JFileChooser fileChooser = new JFileChooser();
269 fileChooser.setDialogType(type);
270 if (defaultFilename != null) {
271 fileChooser.setSelectedFile(new File(currentDir, defaultFilename));
272 } else {
273 fileChooser.setCurrentDirectory(currentDir);
274 }
275 if (filters != null) {
276 for (int i = 0; i < filters.length; i++) {
277 fileChooser.addChoosableFileFilter(filters[i]);
278 }
279 }
280 int result;
281 if (type == JFileChooser.SAVE_DIALOG) {
282 result = fileChooser.showSaveDialog(parent);
283 } else {
284 result = fileChooser.showOpenDialog(parent);
285 }
286 if (result == JFileChooser.CANCEL_OPTION || result == JFileChooser.ERROR_OPTION) {
287 return null;
288 } else {
289 currentDir = fileChooser.getCurrentDirectory();
290 File f = fileChooser.getSelectedFile();
291 if (f.isDirectory()) {
292 f = new File(f, defaultFilename);
293 }
294 return f;
295 }
296 }
297
298 }