EMMA Coverage Report (generated Fri Feb 14 08:28:31 UTC 2014)
[all classes][org.qedeq.base.io]

COVERAGE SUMMARY FOR SOURCE FILE [IoUtility.java]

nameclass, %method, %block, %line, %
IoUtility.java100% (1/1)98%  (49/50)91%  (1455/1594)91%  (393.7/433)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class IoUtility100% (1/1)98%  (49/50)91%  (1455/1594)91%  (393.7/433)
IoUtility (): void 0%   (0/1)0%   (0/3)0%   (0/2)
createNecessaryDirectories (File): void 100% (1/1)52%  (14/27)80%  (4/5)
stringToReader (String): Reader 100% (1/1)62%  (10/16)33%  (1/3)
loadFileBinary (File): byte [] 100% (1/1)71%  (44/62)77%  (11.5/15)
sleep (int): void 100% (1/1)74%  (17/23)77%  (5.4/7)
isSymbolicLink (File): boolean 100% (1/1)78%  (32/41)75%  (9/12)
getStartDirectory (String): File 100% (1/1)80%  (35/44)83%  (5.8/7)
saveFileBinary (File, byte []): void 100% (1/1)83%  (20/24)93%  (6.5/7)
deleteDir (File, FileFilter): boolean 100% (1/1)84%  (49/58)74%  (14.9/20)
saveFile (File, String): void 100% (1/1)85%  (22/26)94%  (7.5/8)
saveFile (File, String, String): void 100% (1/1)86%  (24/28)93%  (6.5/7)
deleteDir (File, boolean): boolean 100% (1/1)86%  (56/65)77%  (16.9/22)
saveFile (InputStream, File): void 100% (1/1)89%  (34/38)96%  (10.6/11)
loadFile (URL, StringBuffer): void 100% (1/1)90%  (36/40)96%  (10.6/11)
loadFile (URL, StringBuffer, String): void 100% (1/1)90%  (37/41)96%  (10.6/11)
loadStreamWithoutException (InputStream, int): String 100% (1/1)92%  (33/36)81%  (11.3/14)
loadFile (File, StringBuffer): void 100% (1/1)92%  (45/49)96%  (12.5/13)
loadFile (File, StringBuffer, String): void 100% (1/1)92%  (46/50)95%  (10.5/11)
copyFile (File, File): void 100% (1/1)92%  (48/52)97%  (14.6/15)
getJavaVersion (): int [] 100% (1/1)92%  (73/79)81%  (17/21)
waitln (): void 100% (1/1)93%  (14/15)80%  (4/5)
compareFilesBinary (File, File): boolean 100% (1/1)94%  (84/89)95%  (21/22)
compareTextFiles (File, File, int, String): boolean 100% (1/1)95%  (106/111)97%  (30/31)
getWorkingEncoding (String): String 100% (1/1)96%  (24/25)86%  (6/7)
close (InputStream): void 100% (1/1)100% (7/7)100% (5/5)
close (OutputStream): void 100% (1/1)100% (7/7)100% (5/5)
close (Reader): void 100% (1/1)100% (7/7)100% (5/5)
close (Writer): void 100% (1/1)100% (7/7)100% (5/5)
compareTextFiles (File, File, String): boolean 100% (1/1)100% (152/152)100% (39/39)
copy (File, File): void 100% (1/1)100% (40/40)100% (9/9)
copy (String, String): void 100% (1/1)100% (10/10)100% (2/2)
createRelativePath (File, File): String 100% (1/1)100% (32/32)100% (5/5)
getDefaultEncoding (): String 100% (1/1)100% (2/2)100% (1/1)
getSortedSystemProperties (): String [][] 100% (1/1)100% (43/43)100% (11/11)
getUserHomeDirectory (): File 100% (1/1)100% (8/8)100% (1/1)
isCr (int): boolean 100% (1/1)100% (22/22)100% (1/1)
isWebStarted (): boolean 100% (1/1)100% (11/11)100% (2/2)
listFilesRecursively (File, FileFilter): List 100% (1/1)100% (33/33)100% (8/8)
listFilesRecursivelyIntern (File, FileFilter): List 100% (1/1)100% (37/37)100% (9/9)
loadFile (String, String): String 100% (1/1)100% (11/11)100% (3/3)
loadFile (String, StringBuffer, String): void 100% (1/1)100% (8/8)100% (2/2)
loadProperties (URL): Properties 100% (1/1)100% (24/24)100% (8/8)
loadReader (Reader, StringBuffer): void 100% (1/1)100% (15/15)100% (4/4)
loadStream (InputStream, StringBuffer): void 100% (1/1)100% (15/15)100% (4/4)
printAllSystemProperties (): void 100% (1/1)100% (30/30)100% (7/7)
saveFile (File, StringBuffer): void 100% (1/1)100% (5/5)100% (2/2)
saveFile (File, StringBuffer, String): void 100% (1/1)100% (6/6)100% (2/2)
saveFile (String, String): void 100% (1/1)100% (7/7)100% (2/2)
saveFile (String, StringBuffer): void 100% (1/1)100% (8/8)100% (2/2)
saveFile (URL, File): void 100% (1/1)100% (5/5)100% (2/2)

1/* This file is part of the project "Hilbert II" - http://www.qedeq.org
2 *
3 * Copyright 2000-2014,  Michael Meyling <mime@qedeq.org>.
4 *
5 * "Hilbert II" is free software; you can redistribute
6 * it and/or modify it under the terms of the GNU General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15 
16package org.qedeq.base.io;
17 
18import java.io.BufferedOutputStream;
19import java.io.BufferedReader;
20import java.io.BufferedWriter;
21import java.io.ByteArrayInputStream;
22import java.io.File;
23import java.io.FileFilter;
24import java.io.FileInputStream;
25import java.io.FileOutputStream;
26import java.io.FileReader;
27import java.io.FileWriter;
28import java.io.IOException;
29import java.io.InputStream;
30import java.io.InputStreamReader;
31import java.io.OutputStream;
32import java.io.OutputStreamWriter;
33import java.io.Reader;
34import java.io.UnsupportedEncodingException;
35import java.io.Writer;
36import java.net.URL;
37import java.nio.charset.Charset;
38import java.util.ArrayList;
39import java.util.Arrays;
40import java.util.Enumeration;
41import java.util.Iterator;
42import java.util.List;
43import java.util.Map;
44import java.util.Properties;
45import java.util.StringTokenizer;
46import java.util.TreeMap;
47 
48import org.apache.commons.lang.SystemUtils;
49 
50 
51/**
52 * A collection of useful static methods for input and output.
53 *
54 * LATER mime 20070101: use StringBuilder instead of StringBuffer if working under JDK 1.5
55 *
56 * @author  Michael Meyling
57 */
58public final class IoUtility {
59 
60    /**
61     * Constructor, should never be called.
62     */
63    private IoUtility() {
64        // don't call me
65    }
66 
67    /**
68     * Get default encoding for this system.
69     *
70     * @return  Default encoding for this system.
71     */
72    public static String getDefaultEncoding() {
73        return SystemUtils.FILE_ENCODING;
74// mime 20090630: under ubuntu the following gave the encoding ASCII:
75//        return new InputStreamReader(
76//              new ByteArrayInputStream(new byte[0])).getEncoding();
77// but it was: file.encoding="ANSI_X3.41968"
78    }
79 
80    /**
81     * Get working Java encoding.
82     *
83     * @param   encoding    Try this encoding.
84     * @return              This is <code>encoding</code> if it is supported. Or an other
85     *                      encoding that is supported by this system.
86     */
87    public static String getWorkingEncoding(final String encoding) {
88        if (encoding != null) {
89            try {
90                if (Charset.isSupported(encoding)
91                        && Charset.forName(encoding).canEncode()) {
92                    return encoding;
93                }
94            } catch (RuntimeException e) {
95                // ignore
96            }
97        }
98        // we must inform someone, but using
99        // Trace within this class is not wise, because it is used
100        // before the Trace is initialized.
101        System.err.println("not supported encoding: " + encoding);
102        return "ISO-8859-1";    // every system must support this
103    }
104 
105    /**
106     * Reads a file and returns the contents as a <code>String</code>.
107     *
108     * @param   filename    Name of the file (could include path).
109     * @param   encoding    Take this encoding.
110     * @return  Contents of file.
111     * @throws  IOException File exception occurred.
112     */
113    public static String loadFile(final String filename, final String encoding)
114            throws IOException {
115 
116        final StringBuffer buffer = new StringBuffer();
117        loadFile(filename, buffer, encoding);
118        return buffer.toString();
119    }
120 
121    /**
122     * Reads contents of a file into a string buffer.
123     *
124     * @param   filename    Name of the file (could include path).
125     * @param   buffer      Buffer to fill with file contents.
126     * @param   encoding    Take this encoding.
127     * @throws  IOException File exception occurred.
128     */
129    public static void loadFile(final String filename,
130            final StringBuffer buffer, final String encoding)
131            throws IOException {
132        loadFile(new File(filename), buffer, encoding);
133    }
134 
135    /**
136     * Reads contents of a stream into a string buffer. Stream is not closed.
137     *
138     * @param   in          This stream will be loaded.
139     * @param   buffer      Buffer to fill with file contents.
140     * @throws  IOException File exception occurred.
141     *
142     * @deprecated  Use {@link #loadReader(Reader, StringBuffer)}.
143     */
144    public static void loadStream(final InputStream in, final StringBuffer buffer)
145            throws IOException {
146 
147        buffer.setLength(0);
148        int c;
149        while ((c = in.read()) >= 0) {
150            buffer.append((char) c);
151        }
152    }
153 
154    /**
155     * Returns contents of a stream into a string, respecting a maximum length.
156     * No exceptions are thrown. Stream is not closed.
157     *
158     * @param   in          This stream will be loaded.
159     * @param   maxLength   This length is not exceeded.
160     * @return  readData    Data read, is not <code>null</code>.
161     */
162    public static String loadStreamWithoutException(final InputStream in, final int maxLength) {
163 
164        if (in == null) {
165            return "";
166        }
167        final StringBuffer buffer = new StringBuffer();
168        buffer.setLength(0);
169        try {
170            int counter = 0;
171            int c;
172            while (counter++ < maxLength) {
173                c = in.read();
174                if (c < 0) {
175                    break;
176                }
177                buffer.append((char) c);
178            }
179        } catch (IOException e) {
180            // ignored
181        } catch (RuntimeException e) {
182            // ignored
183        }
184        return buffer.toString();
185    }
186 
187    /**
188     * Reads contents of a {@link Reader} into a string buffer. Reader is not closed.
189     *
190     * @param   in          This reader will be loaded.
191     * @param   buffer      Buffer to fill with file contents.
192     * @throws  IOException File exception occurred.
193     */
194    public static void loadReader(final Reader in, final StringBuffer buffer)
195            throws IOException {
196 
197        buffer.setLength(0);
198        int c;
199        while ((c = in.read()) >= 0) {
200            buffer.append((char) c);
201        }
202    }
203 
204    /**
205     * Reads contents of a file into a string buffer. Uses default encoding.
206     *
207     * @param   file        This file will be loaded.
208     * @param   buffer      Buffer to fill with file contents.
209     * @throws  IOException File exception occurred.
210     *
211     * @deprecated  Use {@link #loadFile(File, StringBuffer, String)}.
212     */
213    public static void loadFile(final File file,
214            final StringBuffer buffer)
215            throws IOException {
216 
217        final int size = (int) file.length();
218        final char[] data = new char[size];
219        buffer.setLength(0);
220        FileReader in = null;
221        try {
222            in = new FileReader(file);
223            int charsread = 0;
224            while (charsread < size) {
225                charsread += in.read(data, charsread, size - charsread);
226            }
227        } finally {
228            close(in);
229        }
230        buffer.insert(0, data);
231    }
232 
233    /**
234     * Reads contents of a file into a string buffer.
235     *
236     * @param   file        This file will be loaded.
237     * @param   buffer      Buffer to fill with file contents.
238     * @param   encoding    Take this encoding.
239     * @throws  IOException File exception occurred.
240     */
241    public static void loadFile(final File file,
242            final StringBuffer buffer, final String encoding)
243            throws IOException {
244 
245        buffer.setLength((int) file.length());    // ensure capacity
246        buffer.setLength(0);
247        final InputStreamReader in = new InputStreamReader(new FileInputStream(file), encoding);
248        final char[] data = new char[10 * 1024];
249 
250        try {
251            int charsread = 0;
252            while (0 < (charsread = in.read(data, 0, data.length))) {
253                buffer.append(data, 0, charsread);
254            }
255        } finally {
256            in.close();
257        }
258    }
259 
260    /**
261     * Reads a file and returns the contents as a <code>String</code>.
262     *
263     * @param   file        File to load from.
264     * @return  Contents of file.
265     * @throws  IOException File exception occurred.
266     */
267    public static final byte[] loadFileBinary(final File file) throws IOException {
268        final int size = (int) file.length();
269        final FileInputStream in = new FileInputStream(file);
270        try {
271            final byte[] data = new byte[size];
272            int charsread = 0;
273            while (charsread < size) {
274                final int read = in.read(data, charsread, size - charsread);
275                if (read == -1) {
276                    final byte[] result = new byte[charsread];
277                    System.arraycopy(data, 0, result, 0, charsread);
278                    return result;
279                }
280                charsread += read;
281            }
282            in.close();
283            return data;
284        } finally {
285            close(in);
286        }
287    }
288 
289 
290    /**
291     * Reads contents of an URL into a string buffer. The filling is character set dependent.
292     * Content is added to the end of buffer. (Existing data is not cleared.)
293     * <p>
294     * All parameters should not be <code>null</code>.
295     * @param   url         This URL will be loaded.
296     * @param   buffer      Buffer to fill with file contents.
297     * @throws  IOException Reading failed.
298     *
299     * @deprecated  Choose correct encoding.
300     */
301    public static void loadFile(final URL url, final StringBuffer buffer) throws IOException {
302        InputStream in = null;
303        BufferedReader dis = null;
304        try {
305            in = url.openStream();
306            dis = new BufferedReader(new InputStreamReader(in));
307            int i;
308            while ((i = dis.read()) != -1) {
309                buffer.append((char) i);
310            }
311        } finally {
312            close(in);
313            close(dis);
314        }
315    }
316 
317    /**
318     * Reads contents of an URL into a StringBuffer. The filling is character set dependent. The
319     * buffer is not cleared, contents is just added.
320     * <p>
321     * All parameters should not be <code>null</code>.
322     * @param   url         This URL will be loaded.
323     * @param   buffer      Buffer to fill with file contents.
324     * @param   encoding    Take this encoding.
325     * @throws  IOException Reading failed.
326     */
327    public static void loadFile(final URL url, final StringBuffer buffer, final String encoding)
328            throws IOException {
329        InputStream in = null;
330        BufferedReader dis = null;
331        try {
332            in = url.openStream();
333            dis = new BufferedReader(new InputStreamReader(in, encoding));
334            int i;
335            while ((i = dis.read()) != -1) {
336                buffer.append((char) i);
337            }
338        } finally {
339            close(in);
340            close(dis);
341        }
342    }
343 
344    /**
345     * Save binary contents of an URL into a file. Existing files are overwritten.
346     *
347     * @param   url     This URL will be loaded.
348     * @param   file    Write into this file.
349     * @throws  IOException Reading or writing failed.
350     */
351    public static void saveFile(final URL url, final File file) throws IOException {
352        saveFile(url.openStream(), file);
353    }
354 
355    /**
356     * Save binary contents of an input stream into a file. The input stream is closed even
357     * if exceptions occur.  Existing files are overwritten.
358     * @param   in      Read this stream.
359     * @param   file    Write into this file.
360     *
361     * @throws  IOException Reading or writing failed.
362     */
363    public static void saveFile(final InputStream in, final File file) throws IOException {
364        createNecessaryDirectories(file);
365        FileOutputStream out = null;
366        try {
367            out = new FileOutputStream(file);
368            final byte[] data = new byte[8 * 1024];
369            int length;
370            while ((length = in.read(data)) != -1) {
371                out.write(data, 0, length);
372            }
373        } finally {
374            close(in);
375            close(out);
376        }
377    }
378 
379    /**
380     * Convert String into a {@link Reader}.
381     *
382     * <a href="http://bugs.sun.com/bugdatabase/view_bug.do;:WuuT?bug_id=4094886">
383     * Bug ID: 4094886</a>
384     *
385     * @param   data    Convert this.
386     * @return  Resulting reader.
387     */
388    public static final Reader stringToReader(final String data) {
389        try {
390            return new InputStreamReader(new ByteArrayInputStream(data.getBytes("ISO-8859-1")));
391        } catch (UnsupportedEncodingException e) {
392            // should never occur
393            throw new RuntimeException(e);
394        }
395    }
396 
397    /**
398     * Saves a <code>String</code> into a file. Existing files are overwritten.
399     *
400     * @param   filename    Name of the file (could include path).
401     * @param   text        Data to save in the file.
402     * @throws  IOException File exception occurred.
403     *
404     * @deprecated  Use {@link #saveFile(File, String, String)} that has an encoding.
405     */
406    public static void saveFile(final String filename, final String text)
407            throws IOException {
408        saveFile(new File(filename), text);
409    }
410 
411    /**
412     * Saves a <code>StringBuffer</code> in a file. Existing files are overwritten.
413     *
414     * @param   filename    Name of the file (could include path).
415     * @param   text        Data to save in the file.
416     * @throws  IOException File exception occurred.
417     *
418     * @deprecated  Use {@link #saveFile(File, StringBuffer, String)} that has an encoding.
419     */
420    public static void saveFile(final String filename, final StringBuffer text)
421            throws IOException {
422        saveFile(new File(filename), text.toString());
423    }
424 
425    /**
426     * Saves a <code>StringBuffer</code> in a file. Existing files are overwritten.
427     *
428     * @param   file        File to save into.
429     * @param   text        Data to save in the file.
430     * @throws  IOException File exception occurred.
431     *
432     * @deprecated  Use {@link #saveFile(File, StringBuffer, String)} that has an encoding
433     * parameter.
434     */
435    public static void saveFile(final File file, final StringBuffer text)
436            throws IOException {
437        saveFile(file, text.toString());
438    }
439 
440    /**
441     * Saves a <code>String</code> in a file. Uses default encoding.  Existing files are
442     * overwritten.
443     *
444     * @param   file        File to save the data in.
445     * @param   text        Data to save in the file.
446     * @throws  IOException File exception occurred.
447     *
448     * @deprecated  Use {@link #saveFile(File, String, String)} that has an encoding parameter.
449     */
450    public static void saveFile(final File file, final String text)
451            throws IOException {
452        createNecessaryDirectories(file);
453        BufferedWriter out = null;
454        try {
455            out = new BufferedWriter(new FileWriter(file));
456            out.write(text);
457        } finally {
458            close(out);
459        }
460    }
461 
462    /**
463     * Saves a <code>String</code> in a file.  Existing files are overwritten.
464     *
465     * @param   file        File to save the data in.
466     * @param   text        Data to save in the file.
467     * @param   encoding    Use this encoding.
468     * @throws  IOException File exception occurred.
469     */
470    public static void saveFile(final File file, final StringBuffer text, final String encoding)
471            throws IOException {
472        saveFile(file, text.toString(), encoding);
473    }
474 
475    /**
476     * Saves a <code>String</code> in a file.
477     *
478     * @param   file        File to save the data in.
479     * @param   text        Data to save in the file.
480     * @param   encoding    Use this encoding.
481     * @throws  IOException File exception occurred.
482     */
483    public static void saveFile(final File file, final String text, final String encoding)
484            throws IOException {
485        createNecessaryDirectories(file);
486        BufferedWriter out = new BufferedWriter(
487            new OutputStreamWriter(new FileOutputStream(file), encoding));
488        try {
489            out.write(text);
490        } finally {
491            out.close();
492        }
493    }
494 
495    /**
496     * Saves a <code>data</code> in a file. Existing files are overwritten.
497     *
498     * @param   file        File to save the data in.
499     * @param   data        Data to save in the file.
500     * @throws  IOException File exception occurred.
501     */
502    public static void saveFileBinary(final File file, final byte[] data)
503            throws IOException {
504        createNecessaryDirectories(file);
505        BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(file));
506        try {
507            out.write(data);
508        } finally {
509            out.close();
510        }
511    }
512 
513    /**
514     * Copies a file to a different location.
515     *
516     * @param   from    Copy source.
517     * @param   to      Copy destination.
518     * @throws  IOException File exception occurred.
519     */
520    public static void copyFile(final File from, final File to)
521            throws IOException {
522 
523        if (from.getCanonicalFile().equals(to.getCanonicalFile())) {
524            return;
525        }
526        createNecessaryDirectories(to);
527        FileInputStream in = null;
528        FileOutputStream out = null;
529        try {
530            in = new FileInputStream(from);
531            out = new FileOutputStream(to);
532 
533            byte[] data = new byte[8 * 1024];
534            int length;
535            while ((length = in.read(data)) != -1) {
536                out.write(data, 0, length);
537            }
538        } finally {
539            close(in);
540            close(out);
541        }
542    }
543 
544    /**
545     * Copy one file or directory to another location.
546     * If targetLocation does not exist, it will be created.
547     *
548     * @param   sourceLocation  Copy from here. This can be a file or a directory.
549     * @param   targetLocation  Copy to this location. If source is a file this must be a file too.
550     * @throws  IOException     Something went wrong.
551     */
552    public static void copy(final String sourceLocation, final String targetLocation)
553            throws IOException {
554        copy(new File(sourceLocation), new File(targetLocation));
555    }
556 
557    /**
558     * Copy one directory to another location.
559     * If targetLocation does not exist, it will be created.
560     *
561     * @param   sourceLocation  Copy from here.
562     * @param   targetLocation  Copy to this location
563     * @throws  IOException     Something went wrong.
564     */
565    public static void copy(final File sourceLocation, final File targetLocation)
566            throws IOException {
567 
568        if (sourceLocation.isDirectory()) {
569            if (!targetLocation.exists()) {
570                targetLocation.mkdir();
571            }
572            String[] children = sourceLocation.list();
573            for (int i = 0; i < children.length; i++) { // recursive call for all children
574                copy(new File(sourceLocation, children[i]),
575                        new File(targetLocation, children[i]));
576            }
577        } else {    // copy file
578            copyFile(sourceLocation, targetLocation);
579        }
580    }
581 
582    /**
583     * List all matching files. Searches all matching sub directories recursively.
584     * Remember to return <code>true</code> for <code>accept(File pathname)</code> if
585     * <code>pathname</code> is a directory if you want to search all sub directories!
586     * If <code>sourceLocation</code> is a single file, this is the only file that will
587     * be in the resulting list.
588     *
589     * @param   sourceLocation  Check all files in this directory. (Or add this single file.)
590     * @param   filter          Accept only these directories and files.
591     * @return  List of matching files. Contains no directories.
592     * @throws  IOException     Something went wrong.
593     */
594    public static List listFilesRecursively(final File sourceLocation, final FileFilter filter)
595            throws IOException {
596        final List result = new ArrayList();
597        if (sourceLocation.isDirectory()) {
598            final File[] children = sourceLocation.listFiles();
599            for (int i = 0; i < children.length; i++) { // recursive call for all children
600                result.addAll(listFilesRecursivelyIntern(children[i], filter));
601            }
602        } else {
603            result.add(sourceLocation);
604        }
605        return result;
606    }
607 
608    /**
609     * List all matching files. Searches all matching sub directories recursively.
610     * Remember to return <code>true</code> for <code>accept(File pathname)</code> if
611     * <code>pathname</code> is a directory if you want to search all sub directories!
612     *
613     * @param   sourceLocation  Check all files in this directory.
614     * @param   filter          Accept only these directories and files.
615     * @return  List of matching files. Contains no directories.
616     * @throws  IOException     Something went wrong.
617     */
618    private static List listFilesRecursivelyIntern(final File sourceLocation,
619            final FileFilter filter) throws IOException {
620        final List result = new ArrayList();
621        if (filter.accept(sourceLocation)) {
622            if (sourceLocation.isDirectory()) {
623                File[] children = sourceLocation.listFiles();
624                for (int i = 0; i < children.length; i++) { // recursive call for all children
625                    result.addAll(listFilesRecursivelyIntern(children[i], filter));
626                }
627            } else {
628                result.add(sourceLocation);
629            }
630        }
631        return result;
632    }
633 
634    /**
635     * Compare two files binary.
636     *
637     * @param   from    Compare source. This file must be <code>null</code> or be an existing file.
638     * @param   with    Compare with this file. This file must be <code>null</code> or be an
639     *                  existing file.
640     * @return  Is the contents of the two files binary equal?
641     * @throws  IOException File exception occurred.
642     */
643    public static boolean compareFilesBinary(final File from, final File with)
644            throws IOException {
645        if (from == null && with == null) {
646            return true;
647        }
648        if (from == null || with == null) {
649            return false;
650        }
651        if (from.getAbsoluteFile().equals(with.getAbsoluteFile())) {
652            return true;
653        }
654        if (from.length() != with.length()) {
655            return false;
656        }
657        byte[] dataOne = new byte[8 * 1024];
658        byte[] dataTwo = new byte[8 * 1024];
659        int length;
660 
661        FileInputStream one = null;
662        FileInputStream two = null;
663        try {
664            one = new FileInputStream(from);
665            two = new FileInputStream(with);
666 
667            while ((length = one.read(dataOne)) != -1) {
668                if (length != two.read(dataTwo)) {
669                    return false;
670                }
671                if (!Arrays.equals(dataOne, dataTwo)) {
672                    return false;
673                }
674            }
675            return true;
676        } finally {
677            close(one);
678            close(two);
679        }
680    }
681 
682    /**
683     * Compare two text files. Ignores different line separators. As there are:
684     * LF, CR, CR + LF, NEL, FF, LS, PS.
685     *
686     * @param   from        Compare source.
687     * @param   with        Compare with this file.
688     * @param   encoding    Use this character encoding. Must not be <code>null</code>.
689     * @return  Is the contents of the two text files equal?
690     * @throws  IOException File exception occurred or encoding is not supported.
691     * @throws  NullPointerException    Is encoding different from <code>null</code>?
692     */
693    public static boolean compareTextFiles(final File from, final File with, final String encoding)
694            throws IOException {
695        if (from == null && with == null) {
696            return true;
697        }
698        if (from == null || with == null) {
699            return false;
700        }
701        if (from.getAbsoluteFile().equals(with.getAbsoluteFile())) {
702            return true;
703        }
704 
705        BufferedReader one = null;
706        BufferedReader two = null;
707        FileInputStream fromIn = null;
708        FileInputStream withIn = null;
709        try {
710            fromIn = new FileInputStream(from);
711            one = new BufferedReader(new InputStreamReader(fromIn, encoding));
712            withIn = new FileInputStream(with);
713            two = new BufferedReader(new InputStreamReader(withIn, encoding));
714 
715            boolean crOne = false;
716            boolean crTwo = false;
717            do {
718                int readOne = one.read();
719                int readTwo = two.read();
720                if (readOne == readTwo) {
721                    if (readOne < 0) {
722                        break;
723                    }
724                } else {
725                    crOne = readOne == 0x0D;
726                    crTwo = readTwo == 0x0D;
727                    if (crOne) {
728                        readOne = one.read();
729                    }
730                    if (crTwo) {
731                        readTwo = two.read();
732                    }
733                    if (crOne && readOne != 0x0A && isCr(readTwo)) {
734                        readTwo = two.read();
735                    }
736                    if (crTwo && readTwo != 0x0A && isCr(readOne)) {
737                        readOne = one.read();
738                    }
739                    if (readOne != readTwo && (!isCr(readOne) && !isCr(readTwo))) {
740                        return false;
741                    }
742                }
743            } while (true);
744            return true;
745        } finally {
746            close(fromIn);
747            close(one);
748            close(two);
749            close(withIn);
750        }
751    }
752 
753    /**
754     * Compare two text files. Ignores different line separators. As there are:
755     * LF, CR, CR + LF
756     *
757     * @param   from        Compare source.
758     * @param   with        Compare with this file.
759     * @param   startAtLine Start comparing at this line (beginning with 0).
760     * @param   encoding    Use this character encoding. Must not be <code>null</code>.
761     * @return  Is the contents of the two text files equal?
762     * @throws  IOException File exception occurred or encoding is not supported.
763     * @throws  NullPointerException    Is encoding different from <code>null</code>?
764     */
765    public static boolean compareTextFiles(final File from, final File with, final int startAtLine,
766            final String encoding) throws IOException {
767 
768        if (from == null && with == null) {
769            return true;
770        }
771        if (from == null || with == null) {
772            return false;
773        }
774        if (from.getAbsoluteFile().equals(with.getAbsoluteFile())) {
775            return true;
776        }
777        if (startAtLine < 0) {
778            return true;
779        }
780        BufferedReader one = null;
781        BufferedReader two = null;
782        FileInputStream fromIn = null;
783        FileInputStream withIn = null;
784        try {
785            fromIn = new FileInputStream(from);
786            one = new BufferedReader(new InputStreamReader(fromIn, encoding));
787            withIn = new FileInputStream(with);
788            two = new BufferedReader(new InputStreamReader(withIn, encoding));
789            int pos = 0;
790            do {
791                String lineOne = one.readLine();
792                String lineTwo = two.readLine();
793                if (lineOne == null) {
794                    if (lineTwo == null) {
795                        break;
796                    }
797                    return false;
798                }
799                if (pos++ >= startAtLine && !lineOne.equals(lineTwo)) {
800                    return false;
801                }
802            } while (true);
803            return true;
804        } finally {
805            close(fromIn);
806            close(one);
807            close(two);
808            close(withIn);
809        }
810    }
811 
812    /**
813     * Test if character is LF, CR, NEL, FF, LS, PS.
814     * @param   c   Character to test.
815     * @return  Is character a line terminator?
816     */
817    private static boolean isCr(final int c) {
818        return c == 0x0A || c == 0x0D || c == 0x85 || c == 0x0C || c == 0x2028 || c == 0x2029;
819    }
820 
821    /**
822     * Delete file directory recursive.
823     *
824     * @param   directory   Directory to delete. Must not be a symbolic link.
825     * @param   deleteDir   Delete directory itself too?
826     * @return  Was deletion successful?
827     */
828    public static boolean deleteDir(final File directory, final boolean deleteDir) {
829 
830        // first we check if the file is a symbolic link
831        try {
832            if (isSymbolicLink(directory)) {
833                return false;
834            }
835        } catch (IOException e) {
836            return false;
837        }
838        final File candir;
839        try {
840            candir = directory.getCanonicalFile();
841        } catch (IOException e) {
842            return false;
843        }
844 
845        // now we go through all of the files and subdirectories in the
846        // directory and delete them one by one
847        boolean success = true;
848        File[] files = candir.listFiles();
849        if (files != null) {
850            for (int i = 0; i < files.length; i++) {
851                File file = files[i];
852 
853                // in case this directory is actually a symbolic link, or it's
854                // empty, we want to try to delete the link before we try
855                // anything
856                boolean deleted = file.delete();
857                if (!deleted) {
858                    // deleting the file failed, so maybe it's a non-empty
859                    // directory
860                    if (file.isDirectory()) {
861                        deleted = deleteDir(file, true);
862                    }
863 
864                    // otherwise, there's nothing else we can do
865                }
866                success = success && deleted;
867            }
868        }
869 
870        // now that we tried to clear the directory out, we can try to delete it
871        if (deleteDir && directory.exists()) {
872            return directory.delete();
873        }
874        return success;
875    }
876 
877    /**
878     * Delete directory contents for all files that match the filter. The main directory itself is
879     * not deleted.
880     *
881     * @param   directory   Directory to scan for files to delete.
882     * @param   filter      Filter files (and directories) to delete.
883     * @return  Was deletion successful?
884     */
885    public static boolean deleteDir(final File directory, final FileFilter filter) {
886        // first we check if the file is a symbolic link
887        try {
888            if (isSymbolicLink(directory)) {
889                return false;
890            }
891        } catch (IOException e) {
892            return false;
893        }
894        final File candir;
895        try {
896            candir = directory.getCanonicalFile();
897        } catch (IOException e) {
898            return false;
899        }
900 
901        // now we go through all of the files and subdirectories in the
902        // directory and delete them one by one
903        boolean success = true;
904        File[] files = candir.listFiles(filter);
905        if (files != null) {
906            for (int i = 0; i < files.length; i++) {
907                File file = files[i];
908 
909                // in case this directory is actually a symbolic link, or it's
910                // empty, we want to try to delete the link before we try
911                // anything
912                boolean deleted = file.delete();
913                if (!deleted) {
914                    // deleting the file failed, so maybe it's a non-empty
915                    // directory
916                    if (file.isDirectory()) {
917                        deleted = deleteDir(file, true);
918                    }
919 
920                    // otherwise, there's nothing else we can do
921                }
922                success = success && deleted;
923            }
924        }
925 
926        return success;
927    }
928 
929    /**
930     * Determines whether the specified file is a symbolic link rather than an actual file.
931     * See {@link
932     * https://svn.apache.org/repos/asf/commons/proper/io/trunk/src/main/java/org/apache/commons/io/FileUtils.java}.
933     * @param   file    File to check.
934     * @return  Is the file is a symbolic link?
935     * @throws  IOException     IO error while checking the file.
936     */
937    public static boolean isSymbolicLink(final File file) throws IOException {
938        if (file == null) {
939            throw new NullPointerException("File must not be null");
940        }
941        // is windows file system in use?
942        if (File.separatorChar == '\\') {
943            // we have no symbolic links
944            return false;
945        }
946        File fileInCanonicalDir = null;
947        if (file.getParent() == null) {
948            fileInCanonicalDir = file;
949        } else {
950            File canonicalDir = file.getParentFile().getCanonicalFile();
951            fileInCanonicalDir = new File(canonicalDir, file.getName());
952        }
953        if (fileInCanonicalDir.getCanonicalFile().equals(fileInCanonicalDir.getAbsoluteFile())) {
954            return false;
955        }
956        return true;
957    }
958 
959    /**
960     * Print current system properties to System.out.
961     */
962    public static void printAllSystemProperties() {
963        Properties sysprops = System.getProperties();
964        for (Enumeration e = sysprops.propertyNames(); e.hasMoreElements(); ) {
965            String key = (String) e.nextElement();
966            String value = sysprops.getProperty(key);
967            System.out.println(key + "=" + value);
968        }
969    }
970 
971    /**
972     * Get home directory of user.
973     *
974     * @return  Home directory of user.
975     */
976    public static File getUserHomeDirectory() {
977        return new File((String) System.getProperties().get("user.home"));
978    }
979 
980    /**
981     * Creates necessary parent directories for a file.
982     *
983     * @param   file    File.
984     * @throws  IOException Creation failed.
985     */
986    public static void createNecessaryDirectories(final File file) throws IOException {
987        if (file != null && file.getParentFile() != null) {
988            file.getParentFile().mkdirs();
989            if (!file.getParentFile().exists()) {
990                throw new IOException("directory creation failed: " + file.getParent());
991            }
992        }
993    }
994 
995    /**
996     * Create relative address from <code>origin</code> to <code>next</code>.
997     * The resulting file path has "/" as directory name separator.
998     * If the resulting file path is the same as origin specifies, we return "".
999     * Otherwise the result will always have an "/" as last character.
1000     *
1001     * @param   origin  This is the original location. Must be a directory.
1002     * @param   next    This should be the next location. Must also be a directory.
1003     * @return  Relative (or if necessary absolute) file path.
1004     */
1005    public static final String createRelativePath(final File origin, final File next) {
1006        if (origin.equals(next)) {
1007            return "";
1008        }
1009        final Path org = new Path(origin.getPath().replace(File.separatorChar, '/'), "");
1010        final Path ne = new Path(next.getPath().replace(File.separatorChar, '/'), "");
1011        return org.createRelative(ne.toString()).toString();
1012    }
1013 
1014    /**
1015     * Waits until a '\n' was read from System.in.
1016     */
1017    public static void waitln() {
1018        System.out.println("\n..press <return> to continue");
1019        try {
1020            (new java.io.BufferedReader(new java.io.InputStreamReader(
1021                System.in))).readLine();
1022        } catch (IOException e) {
1023            // ignore
1024        }
1025    }
1026 
1027    /**
1028     * Closes input stream without exception.
1029     *
1030     * @param   in  Input stream, maybe <code>null</code>.
1031     */
1032    public static void close(final InputStream in) {
1033        if (in != null) {
1034            try {
1035                in.close();
1036            } catch (Exception e) {
1037                // ignore
1038            }
1039        }
1040    }
1041 
1042    /**
1043     * Closes writer without exception.
1044     *
1045     * @param   writer  Writer, maybe <code>null</code>.
1046     */
1047    public static void close(final Writer writer) {
1048        if (writer != null) {
1049            try {
1050                writer.close();
1051            } catch (Exception e) {
1052                // ignore
1053            }
1054        }
1055    }
1056 
1057    /**
1058     * Closes out stream without exception.
1059     *
1060     * @param   out Output stream, maybe <code>null</code>.
1061     */
1062    public static void close(final OutputStream out) {
1063        if (out != null) {
1064            try {
1065                out.close();
1066            } catch (Exception e) {
1067                // ignore
1068            }
1069        }
1070    }
1071 
1072    /**
1073     * Closes input reader without exception.
1074     *
1075     * @param   reader  Reader, maybe <code>null</code>.
1076     */
1077    public static void close(final Reader reader) {
1078        if (reader != null) {
1079            try {
1080                reader.close();
1081            } catch (Exception e) {
1082                // ignore
1083            }
1084        }
1085    }
1086 
1087    /**
1088     * Get start directory for application. Within the start directory all newly created data is
1089     * stored in. If this is no Java Webstart version the result is
1090     * <code>new File(".")</code>. Otherwise the start directory is the subdirectory
1091     * "." concatenated <code>application</code> within <code>user.home</code>.
1092     * If a system property <code>application + ".startDirectory"</code> is defined we take this
1093     * as the start directory.
1094     *
1095     * @param application   Application name, used for Java Webstart version. Should
1096     *                       be written in lowercase letters. A "." is automatically appended at
1097     *                       the beginning.
1098     * @return  Start directory for application.
1099     */
1100    public static final File getStartDirectory(final String application) {
1101        final File startDirectory;
1102        final String property = System.getProperty(application + ".startDirectory");
1103        if (property != null && property.length() > 0) {
1104            startDirectory = new File(property);
1105        } else if (isWebStarted()) {
1106            startDirectory = new File(getUserHomeDirectory(), "." + application);
1107        } else {
1108            startDirectory = new File(".");
1109        }
1110        return startDirectory;
1111    }
1112 
1113    /**
1114     * Was the application started by Java Webstart?
1115     *
1116     * @return  Was the application started by Java Webstart.
1117     */
1118    public static final boolean isWebStarted() {
1119        final String webStart = (String) System.getProperties().get("javawebstart.version");
1120        return webStart != null;
1121    }
1122 
1123    /**
1124     * Loads a property file from given URL.
1125     *
1126     * @param   url     URL to load properties from. Must not be <code>null</code>.
1127     * @return  Loaded properties.
1128     * @throws  IOException             Reading error.
1129     */
1130    public static Properties loadProperties(final URL url)
1131           throws IOException {
1132        Properties newprops = new Properties();
1133        InputStream in = null;
1134        try {
1135            in = url.openStream();
1136            newprops.load(in);
1137        } finally {
1138            close(in);
1139        }
1140        return newprops;
1141    }
1142 
1143    /**
1144     * Sleep my little class.
1145     *
1146     * @param   ms  Milliseconds to wait.
1147     */
1148    public static void sleep(final int ms) {
1149        final Object monitor = new Object();
1150        synchronized (monitor) {
1151            try {
1152                monitor.wait(ms);
1153            } catch (InterruptedException e) {
1154            }
1155        }
1156    }
1157 
1158    /**
1159     * Get currently running java version and subversion numbers. This is the running JRE version.
1160     * If no version could be identified <code>null</code> is returned.
1161     *
1162     * @return  Array of version and subversion numbers.
1163     */
1164    public static int[] getJavaVersion() {
1165        final String version = System.getProperty("java.version");
1166        final List numbers = new ArrayList();
1167        final StringTokenizer tokenizer = new StringTokenizer(version, ".");
1168        while (tokenizer.hasMoreElements()) {
1169            String sub = tokenizer.nextToken();
1170            for (int i = 0; i < sub.length(); i++) {
1171                if (!Character.isDigit(sub.charAt(i))) {
1172                    sub = sub.substring(0, i);
1173                    break;
1174                }
1175            }
1176            try {
1177                numbers.add(new Integer(Integer.parseInt(sub)));
1178            } catch (Exception e) {
1179                e.printStackTrace();
1180                break;
1181            }
1182        }
1183        if (numbers.size() == 0) {
1184            return null;
1185        }
1186        final int[] result = new int[numbers.size()];
1187        for (int i = 0; i < numbers.size(); i++) {
1188            result[i] = ((Integer) numbers.get(i)).intValue();
1189        }
1190        return result;
1191    }
1192 
1193    /**
1194     * Get key sorted list of all System Properties.
1195     *
1196     * @return  Array with the two columns key and value.
1197     */
1198    public static String[][] getSortedSystemProperties() {
1199        final Map map = new TreeMap(System.getProperties());
1200        String[][] rowData = new String[map.size()][2];
1201        int rowNum = 0;
1202        final Iterator iterator = map.entrySet().iterator();
1203        while (iterator.hasNext()) {
1204            Map.Entry entry = (Map.Entry) iterator.next();
1205            rowData[rowNum][0] = (String) entry.getKey();
1206            rowData[rowNum][1] = (String) entry.getValue();
1207            rowNum++;
1208        }
1209        return rowData;
1210    }
1211 
1212}

[all classes][org.qedeq.base.io]
EMMA 2.1.5320 (stable) (C) Vladimir Roubtsov