xref: /aosp_15_r20/external/apache-commons-io/src/site/xdoc/bestpractices.xml (revision 0c4d7b72e49a04598d65c566f44504b95342d75a)
1<?xml version="1.0"?>
2<!--
3Licensed to the Apache Software Foundation (ASF) under one or more
4contributor license agreements.  See the NOTICE file distributed with
5this work for additional information regarding copyright ownership.
6The ASF licenses this file to You under the Apache License, Version 2.0
7(the "License"); you may not use this file except in compliance with
8the License.  You may obtain a copy of the License at
9
10     http://www.apache.org/licenses/LICENSE-2.0
11
12Unless required by applicable law or agreed to in writing, software
13distributed under the License is distributed on an "AS IS" BASIS,
14WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15See the License for the specific language governing permissions and
16limitations under the License.
17-->
18<document>
19 <properties>
20  <title>Best practices</title>
21  <author email="[email protected]">Commons Documentation Team</author>
22 </properties>
23  <body>
24
25    <section name="Best practices">
26        <p>
27            This document presents a number of 'best practices' in the IO area.
28        </p>
29    </section>
30
31    <section name="java.io.File">
32
33        <p>
34            Often, you have to deal with files and filenames. There are many
35            things that can go wrong:
36        </p>
37        <ul>
38            <li>A class works in Unix but doesn't on Windows (or vice versa)</li>
39            <li>Invalid filenames due to double or missing path separators</li>
40            <li>UNC filenames (on Windows) don't work with my home-grown filename utility function</li>
41            <li>etc. etc.</li>
42        </ul>
43        <p>
44            These are good reasons not to work with filenames as Strings.
45            Using java.io.File instead handles many of the above cases nicely.
46            Thus, our best practice recommendation is to use java.io.File
47            instead of String for filenames to avoid platform dependencies.
48        </p>
49        <p>
50            <i>
51            Version 1.1 of commons-io now includes a dedicated filename
52            handling class - <a href="apidocs/index.html?org/apache/commons/io/FilenameUtils.html">FilenameUtils</a>.
53            This does handle many of these filename issues, however we still
54            recommend, wherever possible, that you use java.io.File objects.
55            </i>
56        </p>
57        <p>
58            Let's look at an example.
59        </p>
60        <source>
61 public static String getExtension(String filename) {
62   int index = filename.lastIndexOf('.');
63   if (index == -1) {
64     return "";
65   } else {
66     return filename.substring(index + 1);
67   }
68 }</source>
69        <p>
70            Easy enough? Right, but what happens if someone passes in a full path
71            instead of only a filename? Consider the following, perfectly legal path:
72            "C:\Temp\documentation.new\README".
73            The method as defined above would return "new\README" - definitely
74            not what you wanted.
75        </p>
76        <p>
77            Please use java.io.File for filenames instead of Strings.
78            The functionality that the class provides is well tested.
79            In FileUtils you will find other useful utility functions
80            around java.io.File.
81        </p>
82        <p>
83            Instead of:
84        </p>
85        <source>
86 String tmpdir = "/var/tmp";
87 String tmpfile = tmpdir + System.getProperty("file.separator") + "test.tmp";
88 InputStream in = new java.io.FileInputStream(tmpfile);</source>
89        <p>
90            ...write:
91        </p>
92        <source>
93 File tmpdir = new File("/var/tmp");
94 File tmpfile = new File(tmpdir, "test.tmp");
95 InputStream in = new java.io.FileInputStream(tmpfile);</source>
96
97    </section>
98
99    <section name="Buffering streams">
100        <p>
101            IO performance depends a lot on the buffering strategy. Usually, it's
102            quite fast to read packets with the size of 512 or 1024 bytes because
103            these sizes match well with the packet sizes used on hard disks in
104            file systems or file system caches. But as soon as you have to read only
105            a few bytes and that many times performance drops significantly.
106        </p>
107        <p>
108            Make sure you're properly buffering streams when reading or writing
109            streams, especially when working with files. Just decorate your
110            FileInputStream with a BufferedInputStream:
111        </p>
112        <source>
113 InputStream in = new java.io.FileInputStream(myfile);
114 try {
115   in = new java.io.BufferedInputStream(in);
116
117   in.read(.....
118 } finally {
119   IOUtils.closeQuietly(in);
120 }</source>
121        <p>
122            Pay attention that you're not buffering an already buffered stream. Some
123            components like XML parsers may do their own buffering so decorating
124            the InputStream you pass to the XML parser does nothing but slowing down
125            your code. If you use our CopyUtils or IOUtils you don't need to
126            additionally buffer the streams you use as the code in there already
127            buffers the copy process. Always check the Javadocs for information.
128            Another case where buffering is unnecessary is when you write to a
129            ByteArrayOutputStream since you're writing to memory only.
130        </p>
131    </section>
132
133  </body>
134
135</document>
136