001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.kernel.util;
016    
017    import com.liferay.portal.kernel.log.Log;
018    import com.liferay.portal.kernel.log.LogFactoryUtil;
019    
020    import java.io.FileInputStream;
021    import java.io.FileOutputStream;
022    import java.io.IOException;
023    import java.io.InputStream;
024    import java.io.OutputStream;
025    
026    import java.nio.channels.Channel;
027    import java.nio.channels.FileChannel;
028    
029    /**
030     * @author Brian Wing Shun Chan
031     * @author Raymond Aug??
032     */
033    public class StreamUtil {
034    
035            public static final int BUFFER_SIZE = GetterUtil.getInteger(
036                    System.getProperty(StreamUtil.class.getName() + ".buffer.size"), 8192);
037    
038            public static final boolean FORCE_TIO = GetterUtil.getBoolean(
039                    System.getProperty(StreamUtil.class.getName() + ".force.tio"));
040    
041            public static void cleanUp(Channel channel) {
042                    try {
043                            if (channel != null) {
044                                    channel.close();
045                            }
046                    }
047                    catch (Exception e) {
048                            if (_log.isWarnEnabled()) {
049                                    _log.warn(e, e);
050                            }
051                    }
052            }
053    
054            public static void cleanUp(Channel inputChannel, Channel outputChannel) {
055                    cleanUp(inputChannel);
056                    cleanUp(outputChannel);
057            }
058    
059            public static void cleanUp(InputStream inputStream) {
060                    try {
061                            if (inputStream != null) {
062                                    inputStream.close();
063                            }
064                    }
065                    catch (Exception e) {
066                            if (_log.isWarnEnabled()) {
067                                    _log.warn(e, e);
068                            }
069                    }
070            }
071    
072            public static void cleanUp(
073                    InputStream inputStream, OutputStream outputStream) {
074    
075                    cleanUp(outputStream);
076                    cleanUp(inputStream);
077            }
078    
079            public static void cleanUp(OutputStream outputStream) {
080                    try {
081                            if (outputStream != null) {
082                                    outputStream.flush();
083                            }
084                    }
085                    catch (Exception e) {
086                            if (_log.isWarnEnabled()) {
087                                    _log.warn(e, e);
088                            }
089                    }
090    
091                    try {
092                            if (outputStream != null) {
093                                    outputStream.close();
094                            }
095                    }
096                    catch (Exception e) {
097                            if (_log.isWarnEnabled()) {
098                                    _log.warn(e, e);
099                            }
100                    }
101            }
102    
103            public static void transfer(
104                            InputStream inputStream, OutputStream outputStream)
105                    throws IOException {
106    
107                    transfer(inputStream, outputStream, BUFFER_SIZE, true);
108            }
109    
110            public static void transfer(
111                            InputStream inputStream, OutputStream outputStream, boolean cleanUp)
112                    throws IOException {
113    
114                    transfer(inputStream, outputStream, BUFFER_SIZE, cleanUp);
115            }
116    
117            public static void transfer(
118                            InputStream inputStream, OutputStream outputStream, int bufferSize)
119                    throws IOException {
120    
121                    transfer(inputStream, outputStream, bufferSize, true);
122            }
123    
124            public static void transfer(
125                            InputStream inputStream, OutputStream outputStream, int bufferSize,
126                            boolean cleanUp)
127                    throws IOException {
128    
129                    transfer(inputStream, outputStream, bufferSize, cleanUp, 0);
130            }
131    
132            public static void transfer(
133                            InputStream inputStream, OutputStream outputStream, int bufferSize,
134                            boolean cleanUp, long length)
135                    throws IOException {
136    
137                    if (inputStream == null) {
138                            throw new IllegalArgumentException("Input stream cannot be null");
139                    }
140    
141                    if (outputStream == null) {
142                            throw new IllegalArgumentException("Output stream cannot be null");
143                    }
144    
145                    if (bufferSize <= 0) {
146                            bufferSize = BUFFER_SIZE;
147                    }
148    
149                    try {
150                            if (!FORCE_TIO && (inputStream instanceof FileInputStream) &&
151                                    (outputStream instanceof FileOutputStream)) {
152    
153                                    FileInputStream fileInputStream = (FileInputStream)inputStream;
154                                    FileOutputStream fileOutputStream =
155                                            (FileOutputStream)outputStream;
156    
157                                    transferFileChannel(
158                                            fileInputStream.getChannel(), fileOutputStream.getChannel(),
159                                            length);
160                            }
161                            else {
162                                    transferByteArray(
163                                            inputStream, outputStream, bufferSize, length);
164                            }
165                    }
166                    finally {
167                            if (cleanUp) {
168                                    cleanUp(inputStream, outputStream);
169                            }
170                    }
171            }
172    
173            public static void transfer(
174                            InputStream inputStream, OutputStream outputStream, long length)
175                    throws IOException {
176    
177                    transfer(inputStream, outputStream, BUFFER_SIZE, true, length);
178            }
179    
180            protected static void transferByteArray(
181                            InputStream inputStream, OutputStream outputStream, int bufferSize,
182                            long length)
183                    throws IOException {
184    
185                    byte[] bytes = new byte[bufferSize];
186    
187                    long remainingLength = length;
188    
189                    if (remainingLength > 0) {
190                            while (remainingLength > 0) {
191                                    int readBytes = inputStream.read(
192                                            bytes, 0, (int)Math.min(remainingLength, bufferSize));
193    
194                                    if (readBytes == -1) {
195                                            break;
196                                    }
197    
198                                    outputStream.write(bytes, 0, readBytes);
199    
200                                    remainingLength -= readBytes;
201                            }
202                    }
203                    else {
204                            int value = -1;
205    
206                            while ((value = inputStream.read(bytes)) != -1) {
207                                    outputStream.write(bytes, 0, value);
208                            }
209                    }
210            }
211    
212            protected static void transferFileChannel(
213                            FileChannel inputFileChannel, FileChannel outputFileChannel,
214                            long length)
215                    throws IOException {
216    
217                    long size = 0;
218    
219                    if (length > 0) {
220                            size = length;
221                    }
222                    else {
223                            size = inputFileChannel.size();
224                    }
225    
226                    long position = 0;
227    
228                    while (position < size) {
229                            position += inputFileChannel.transferTo(
230                                    position, size - position, outputFileChannel);
231                    }
232            }
233    
234            private static Log _log = LogFactoryUtil.getLog(StreamUtil.class);
235    
236    }