Java tutorial
/* * Copyright (C) 2008 feilong (venusdrogon@163.com) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.feilong.commons.core.io; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.io.Writer; import java.nio.ByteBuffer; import java.nio.channels.Channels; import java.nio.channels.ReadableByteChannel; import java.nio.channels.WritableByteChannel; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.feilong.commons.core.util.Validator; /** * ??? * * <ul> * <li>{@link #write(InputStream, OutputStream)} ?,, {@code <<>>}</li> * <li>{@link #write(String, String)} </li> * <li>{@link #write(InputStream, String, String)} inputStream ?,??fileName</li> * <li>{@link #write(String, String, String)} /</li> * <li>{@link #write(String, String, String, FileWriteMode)} </li> * </ul> * * ?,? {@link #write(String, String, String, FileWriteMode)}. * * @author <a href="mailto:venusdrogon@163.com"></a> * @version 1.0 Dec 23, 2013 10:23:23 PM * @see "org.springframework.util.StreamUtils" * @see "org.springframework.util.FileCopyUtils" * @see org.apache.commons.io.IOUtils * @since 1.0.0 */ public final class IOWriteUtil { /** The Constant log. */ private static final Logger log = LoggerFactory.getLogger(IOWriteUtil.class); /** Don't let anyone instantiate this class. */ private IOWriteUtil() { //AssertionError?. ?????. ???. //see Effective Java 2nd throw new AssertionError("No " + getClass().getName() + " instances for you!"); } /** * inputStream ?( ??"/"),??fileName. * * <h3>fileAllName ?</h3> * * <blockquote> * <p> * {@code directoryName + "/" + fileName} * </p> * </blockquote> * <p> * .<br> * ?,(?? ) * </p> * * @param inputStream * ? * @param directoryName * ??"/" * @param fileName * ?? * @throws UncheckedIOException * the unchecked io exception * @see com.feilong.commons.core.io.IOWriteUtil#write(InputStream, OutputStream) */ public static void write(InputStream inputStream, String directoryName, String fileName) throws UncheckedIOException { String fileAllName = directoryName + "/" + fileName; // . ?, File file = new File(fileAllName); File fileParent = file.getParentFile(); if (!fileParent.exists()) { fileParent.mkdirs(); } OutputStream outputStream = FileUtil.getFileOutputStream(fileAllName); write(inputStream, outputStream); } /** * ?,, {@code <<>>} .<br> * <b>(? <code>inputStream</code>? <code>outputStream</code>).</b> * * @param inputStream * inputStream * @param outputStream * outputStream * @throws UncheckedIOException * the unchecked io exception * @see java.io.OutputStream#write(byte[], int, int) * @see #write(int, InputStream, OutputStream) * @see org.apache.commons.io.IOUtils#copyLarge(InputStream, OutputStream) */ public static void write(InputStream inputStream, OutputStream outputStream) throws UncheckedIOException { //Just write in blocks instead of copying it entirely into Java's memory first. //The below basic example writes it in blocks of 10KB. //This way you end up with a consistent memory usage of only 10KB instead of the complete content length. //Also the enduser will start getting parts of the content much sooner. write(IOConstants.DEFAULT_BUFFER_LENGTH, inputStream, outputStream); } /** * ?,, {@code <<>>} .<br> * <b>(? <code>inputStream</code>? <code>outputStream</code>).</b> * * @param bufferLength * ?buffer? * @param inputStream * inputStream * @param outputStream * outputStream * @throws UncheckedIOException * the unchecked io exception * @see java.io.OutputStream#write(byte[], int, int) * @see org.apache.commons.io.IOUtils#copyLarge(InputStream, OutputStream) * @see <a href="http://stackoverflow.com/questions/10142409/write-an-inputstream-to-an-httpservletresponse">As creme de la creme with * regard to performance, you could use NIO Channels and ByteBuffer. Create the following utility/helper method in some custom * utility class,</a> * @see #writeUseIO(int, InputStream, OutputStream) * @see #writeUseNIO(int, InputStream, OutputStream) */ public static void write(int bufferLength, InputStream inputStream, OutputStream outputStream) throws UncheckedIOException { writeUseNIO(bufferLength, inputStream, outputStream); //writeUseIO(bufferLength, inputStream, outputStream); } /** * NIO API ?? (). * * @param bufferLength * the buffer length * @param inputStream * the input stream * @param outputStream * the output stream * @throws UncheckedIOException * the unchecked io exception * @since 1.0.8 */ private static void writeUseNIO(int bufferLength, InputStream inputStream, OutputStream outputStream) throws UncheckedIOException { int i = 0; int sumSize = 0; int j = 0; ///2 //As creme de la creme with regard to performance, you could use NIO Channels and ByteBuffer. ReadableByteChannel readableByteChannel = Channels.newChannel(inputStream); WritableByteChannel writableByteChannel = Channels.newChannel(outputStream); ByteBuffer byteBuffer = ByteBuffer.allocate(bufferLength); try { while (readableByteChannel.read(byteBuffer) != -1) { byteBuffer.flip(); j = writableByteChannel.write(byteBuffer); sumSize += j; byteBuffer.clear(); i++; } if (log.isDebugEnabled()) { log.debug("Write data over,sumSize:[{}],bufferLength:[{}],loopCount:[{}]", FileUtil.formatSize(sumSize), bufferLength, i); } } catch (IOException e) { throw new UncheckedIOException(e); } finally { try { if (writableByteChannel != null) { outputStream.close(); writableByteChannel.close(); } if (readableByteChannel != null) { inputStream.close(); readableByteChannel.close(); } } catch (IOException e) { throw new UncheckedIOException(e); } } } /** * IO API??. * * @param bufferLength * the buffer length * @param inputStream * the input stream * @param outputStream * the output stream * @throws UncheckedIOException * the unchecked io exception * @since 1.0.8 * @deprecated use {@link #writeUseNIO(int, InputStream, OutputStream)} */ @Deprecated private static void writeUseIO(int bufferLength, InputStream inputStream, OutputStream outputStream) throws UncheckedIOException { int i = 0; int sumSize = 0; int j = 0; byte[] bytes = new byte[bufferLength]; try { //???bytes ?????? // bytes 0?? 0??? //??? -1?? bytes //? bytes[0] b[1] ? //? b k ? b[0] b[k-1] ?? b[k] b[b.length-1] // InputStream read(b) ?read(b, 0, b.length) while ((j = inputStream.read(bytes)) != -1) { //??? //ClientAbortException: java.net.SocketException: Software caused connection abort: socket write error outputStream.write(bytes, 0, j); i++; sumSize = sumSize + j; //if (log.isDebugEnabled()){ // log.debug( // "write data,index:[{}],bufferLength:[{}],currentLoopLength:[{}],sumSize:[{}]", // i, // bufferLength, // j, // FileUtil.formatSize(sumSize)); //} } if (log.isDebugEnabled()) { log.debug("write data over,sumSize:[{}],bufferLength:[{}],loopCount:[{}]", FileUtil.formatSize(sumSize), bufferLength, i); } //?flush ?????? outputStream.flush(); } catch (IOException e) { throw new UncheckedIOException(e); } finally { try { // ? ,^_^ if (outputStream != null) { outputStream.close(); } if (inputStream != null) { inputStream.close(); } } catch (IOException e) { throw new UncheckedIOException(e); } } } // ******************************************************************************************* /** * * * <ul> * <li>?,;(?)</li> * <li>, , ? {@link FileWriteMode#COVER}.</li> * <li>?encode, {@link CharsetType#GBK}?</li> * </ul> * * @param filePath * * @param content * * @throws UncheckedIOException * the unchecked io exception * @throws IllegalArgumentException * <ul> * <li>filePath,isDirectory</li> * <li>filePath,!canWrite</li> * </ul> * @see FileWriteMode * @see CharsetType */ public static void write(String filePath, String content) throws UncheckedIOException, IllegalArgumentException { String encode = null; write(filePath, content, encode); } /** * /. * * <ul> * <li>?,;(?)</li> * <li>, , ? {@link FileWriteMode#COVER}.</li> * </ul> * * @param filePath * * @param content * * @param encode * ?,isNullOrEmpty, {@link CharsetType#GBK}? {@link CharsetType} * @throws UncheckedIOException * the unchecked io exception * @throws IllegalArgumentException * <ul> * <li>filePath,isDirectory</li> * <li>filePath,!canWrite</li> * </ul> * @see FileWriteMode * @see CharsetType * @see #write(String, String, String, FileWriteMode) */ public static void write(String filePath, String content, String encode) throws UncheckedIOException, IllegalArgumentException { write(filePath, content, encode, FileWriteMode.COVER); } /** * . * * <ul> * <li>?,, (?? )</li> * <li>,? {@link FileWriteMode#APPEND}??</li> * </ul> * * @param filePath * * @param content * * @param encode * ?,isNullOrEmpty, {@link CharsetType#GBK}? {@link CharsetType} * @param fileWriteMode * ? * @throws UncheckedIOException * the unchecked io exception * @throws IllegalArgumentException * <ul> * <li>filePath,isDirectory</li> * <li>filePath,!canWrite</li> * </ul> * @see FileWriteMode * @see CharsetType * @see com.feilong.commons.core.io.FileUtil#cascadeMkdirs(String) * @see java.io.FileOutputStream#FileOutputStream(File, boolean) */ public static void write(String filePath, String content, String encode, FileWriteMode fileWriteMode) throws UncheckedIOException, IllegalArgumentException { if (Validator.isNullOrEmpty(encode)) { encode = CharsetType.GBK; } // **************************************************************************8 File file = FileUtil.cascadeMkdirs(filePath); boolean append = (fileWriteMode == FileWriteMode.APPEND); try { OutputStream outputStream = new FileOutputStream(file, append); Writer outputStreamWriter = new OutputStreamWriter(outputStream, encode); Writer writer = new PrintWriter(outputStreamWriter); writer.write(content); writer.close(); if (log.isInfoEnabled()) { log.info("fileWriteMode:[{}],contentLength:[{}],encode:[{}],fileSize:[{}],absolutePath:[{}]", fileWriteMode, content.length(), encode, FileUtil.getFileFormatSize(file), file.getAbsolutePath()); } } catch (IOException e) { throw new UncheckedIOException(e); } } }