~ubuntu-branches/ubuntu/maverick/commons-io/maverick

« back to all changes in this revision

Viewing changes to xdocs/bestpractices.xml

  • Committer: Bazaar Package Importer
  • Author(s): Wolfgang Baer
  • Date: 2005-10-16 13:44:21 UTC
  • Revision ID: james.westby@ubuntu.com-20051016134421-v2gfddy6iovz449t
Tags: upstream-1.0
ImportĀ upstreamĀ versionĀ 1.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
<?xml version="1.0"?>
 
2
 
 
3
<!--
 
4
    Building IO
 
5
    $Id: bestpractices.xml,v 1.1 2004/01/16 17:05:03 jeremias Exp $
 
6
-->
 
7
 
 
8
<document>
 
9
  <body>
 
10
 
 
11
    <section name="Overview">
 
12
        <p>
 
13
            This document presents a number of "best practices" in the IO area.
 
14
        </p>
 
15
    </section>
 
16
 
 
17
    <section name="java.io.File">
 
18
    
 
19
        <p>
 
20
            Often, you have to deal with files and filenames. There are many
 
21
            things that can go wrong:
 
22
        </p>
 
23
        <ul>
 
24
            <li>A class works in Unix but doesn't on Windows (or vice versa)</li>
 
25
            <li>Invalid filenames due to double or missing path separators</li>
 
26
            <li>UNC filenames (on Windows) don't work with my home-grown filename utility function</li>
 
27
            <li>etc. etc.</li>
 
28
        </ul>
 
29
        <p>
 
30
            These are good reasons not to work with filenames as Strings. Use 
 
31
            java.io.File instead which handles many of the above cases nicely. Too
 
32
            many people are still always using Strings for filenames and risk
 
33
            platform dependencies, for example.
 
34
        </p>
 
35
        <p>
 
36
            Let's look at an example. BTW, it's one of the functions that made us
 
37
            skip the class FilenameUtils for the initial release of Commons IO.
 
38
        </p>
 
39
        <source>
 
40
    public static String getExtension(String filename) {
 
41
        int index = filename.lastIndexOf('.');
 
42
 
 
43
        if (-1 == index) {
 
44
            return "";
 
45
        } else {
 
46
            return filename.substring(index + 1);
 
47
        }
 
48
    }</source>
 
49
        <p>
 
50
            Easy enough? Right, but what happens if someone passes in a full path 
 
51
            instead of only a filename? Consider the following, perfectly legal path:
 
52
            "C:\Temp\documentation.new\README" 
 
53
        </p>
 
54
        <p>
 
55
            Please use java.io.File for filenames instead of Strings. The functionality
 
56
            that the class provides is well tested. In FileUtils you will find other
 
57
            useful utility functions around java.io.File.
 
58
        </p>
 
59
        <p>
 
60
            Instead of:
 
61
        </p>
 
62
        <source>
 
63
    String tmpdir = "/var/tmp";
 
64
    String tmpfile = tmpdir + System.getProperty("file.separator") + "test.tmp";
 
65
    InputStream in = new java.io.FileInputStream(tmpfile);</source>
 
66
        <p>
 
67
            ...write:
 
68
        </p>
 
69
        <source>
 
70
    File tmpdir = new File("/var/tmp");
 
71
    File tmpfile = new File(tmpdir, "test.tmp");
 
72
    InputStream in = new java.io.FileInputStream(tmpfile);</source>
 
73
 
 
74
    </section>
 
75
    
 
76
    <section name="Buffering streams">
 
77
        <p>
 
78
            IO performance depends a lot from the buffering strategy. Usually, it's 
 
79
            quite fast to read packets with the size of 512 or 1024 bytes because
 
80
            these sizes match well with the packet sizes used on harddisks in 
 
81
            file systems or file system caches. But as soon as you have to read only 
 
82
            a few bytes and that many times performance drops significantly.
 
83
        </p>
 
84
        <p>
 
85
            Make sure you're properly buffering streams when reading or writing 
 
86
            streams, especially when working with files. Just decorate your 
 
87
            FileInputStream with a BufferedInputStream:
 
88
        </p>
 
89
        <source>
 
90
            InputStream in = new java.io.FileInputStream(myfile);
 
91
            try {
 
92
                in = new java.io.BufferedInputStream(in);
 
93
                
 
94
                in.read(.....
 
95
            } finally {
 
96
                IOUtils.closeQuietly(in);
 
97
            }
 
98
        </source>
 
99
        <p>
 
100
            Pay attention that you're not buffering an already buffered stream. Some
 
101
            components like XML parsers may do their own buffering so decorating
 
102
            the InputStream you pass to the XML parser does nothing but slowing down
 
103
            your code. If you use our CopyUtils or IOUtils you don't need to 
 
104
            additionally buffer the streams you use as the code in there already
 
105
            buffers the copy process. Always check the Javadocs for information. 
 
106
            Another case where buffering is unnecessary is when you write to a 
 
107
            ByteArrayOutputStream since you're writing to memory only.
 
108
        </p>
 
109
    </section>
 
110
 
 
111
  </body>
 
112
 
 
113
</document>