com.sunchenbin.store.feilong.core.io.IOWriteUtil.java Source code

Java tutorial

Introduction

Here is the source code for com.sunchenbin.store.feilong.core.io.IOWriteUtil.java

Source

/*
 * Copyright (C) 2008 feilong
 *
 * 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.sunchenbin.store.feilong.core.io;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.WritableByteChannel;
import java.nio.charset.Charset;
import java.util.Date;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.sunchenbin.store.feilong.core.date.DateExtensionUtil;
import com.sunchenbin.store.feilong.core.lang.CharsetType;
import com.sunchenbin.store.feilong.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 feilong
 * @version 1.0.6 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.6
 */
public final class IOWriteUtil {

    /** The Constant LOGGER. */
    private static final Logger LOGGER = LoggerFactory.getLogger(IOWriteUtil.class);

    /** ? 10k <code>{@value}</code> */
    public static final int DEFAULT_BUFFER_LENGTH = (int) (10 * FileUtils.ONE_KB);

    /** 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
     *            ??
     * @see com.sunchenbin.store.feilong.core.io.IOWriteUtil#write(InputStream, OutputStream)
     */
    public static void write(InputStream inputStream, String directoryName, String fileName) {
        String filePath = directoryName + "/" + fileName;
        FileUtil.createDirectory(directoryName);
        OutputStream outputStream = FileUtil.getFileOutputStream(filePath);
        write(inputStream, outputStream);
    }

    /**
     * 
     * 
     * <h3>:</h3>
     * 
     * <blockquote>
     * <ul>
     * <li> <code>Validator.isNullOrEmpty(filePath)</code>, {@link NullPointerException}</li>
     * <li>?,, (?? )</li>
     * <li>,?{@link FileWriteMode#APPEND}?</li>
     * <li>? <code>charsetType</code>,{@link CharsetType#UTF8}?</li>
     * </ul>
     * </blockquote>
     *
     * @param filePath
     *            
     * @param content
     *            
     * @see FileWriteMode
     * @see CharsetType
     */
    public static void write(String filePath, String content) {
        String encode = null;
        write(filePath, content, encode);
    }

    /**
     * /.
     * 
     * <h3>:</h3>
     * 
     * <blockquote>
     * <ul>
     * <li> <code>Validator.isNullOrEmpty(filePath)</code>, {@link NullPointerException}</li>
     * <li>?,, (?? )</li>
     * <li>,?{@link FileWriteMode#APPEND}?</li>
     * <li>? <code>charsetType</code>,{@link CharsetType#UTF8}?</li>
     * </ul>
     * </blockquote>
     *
     * @param filePath
     *            
     * @param content
     *            
     * @param encode
     *            ?,isNullOrEmpty, {@link CharsetType#UTF8}? {@link CharsetType}
     * @see FileWriteMode
     * @see CharsetType
     * @see #write(String, String, String, FileWriteMode)
     */
    public static void write(String filePath, String content, String encode) {
        write(filePath, content, encode, FileWriteMode.COVER);//default_fileWriteMode
    }

    /**
     * .
     * 
     * <h3>:</h3>
     * 
     * <blockquote>
     * <ul>
     * <li> <code>Validator.isNullOrEmpty(filePath)</code>, {@link NullPointerException}</li>
     * <li>?,, (?? )</li>
     * <li>,?{@link FileWriteMode#APPEND}?</li>
     * <li>? <code>charsetType</code>,{@link CharsetType#UTF8}?</li>
     * </ul>
     * </blockquote>
     *
     * @param filePath
     *            
     * @param content
     *            
     * @param charsetType
     *            {@link CharsetType} ?,isNullOrEmpty, {@link CharsetType#UTF8}?
     * @param fileWriteMode
     *            ? {@link FileWriteMode}
     * @see java.io.FileOutputStream#FileOutputStream(File, boolean)
     * @see #write(InputStream, OutputStream)
     * @see org.apache.commons.io.FileUtils#writeStringToFile(File, String, Charset, boolean)
     */
    public static void write(String filePath, String content, String charsetType, FileWriteMode fileWriteMode) {
        if (Validator.isNullOrEmpty(filePath)) {
            throw new NullPointerException("filePath can't be null/empty!");
        }
        Date beginDate = new Date();

        String useEncode = Validator.isNullOrEmpty(charsetType) ? CharsetType.UTF8 : charsetType;
        FileWriteMode useFileWriteMode = Validator.isNullOrEmpty(fileWriteMode) ? FileWriteMode.COVER
                : fileWriteMode;

        FileUtil.createDirectoryByFilePath(filePath);

        InputStream inputStream = IOUtils.toInputStream(content, Charset.forName(useEncode));
        OutputStream outputStream = FileUtil.getFileOutputStream(filePath, useFileWriteMode);

        write(inputStream, outputStream);

        if (LOGGER.isInfoEnabled()) {
            File file = new File(filePath);
            LOGGER.info("fileWriteMode:[{}],encode:[{}],contentLength:[{}],fileSize:[{}],absolutePath:[{}],time:{}",
                    useFileWriteMode, useEncode, content.length(), FileUtil.getFileFormatSize(file),
                    file.getAbsolutePath(), DateExtensionUtil.getIntervalForView(beginDate, new Date()));
        }
    }

    // *******************************************************************************************

    /**
     * ?,,  {@code  <<>>}.
     * 
     * <p span style="color:red">
     * <b>(?, <code>inputStream</code>? <code>outputStream</code>).</b>
     * </p>
     * 
     * <p>
     * Just write in blocks instead of copying it entirely into Java's memory first.<br>
     * The below basic example writes it in blocks of 10KB.<br>
     * This way you end up with a consistent memory usage of only 10KB instead of the complete content length.<br>
     * Also the enduser will start getting parts of the content much sooner.
     * </p>
     * 
     * @param inputStream
     *            inputStream
     * @param outputStream
     *            outputStream
     * @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) {
        write(DEFAULT_BUFFER_LENGTH, inputStream, outputStream);
    }

    /**
     * ?,,  {@code  <<>>} .
     * 
     * <p span style="color:red">
     * <b>(?, <code>inputStream</code>? <code>outputStream</code>).</b>
     * </p>
     *
     * @param bufferLength
     *            ?buffer?
     * @param inputStream
     *            inputStream
     * @param outputStream
     *            outputStream
     * @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 #writeUseNIO(int, InputStream, OutputStream)
     */
    public static void write(int bufferLength, InputStream inputStream, OutputStream outputStream) {
        writeUseNIO(bufferLength, inputStream, outputStream);
    }

    /**
     * NIO API ?? ().
     * 
     * <h3>NIO</h3>
     * 
     * <blockquote>
     * <p>
     * nionew io,jdk1.4,??<br>
     * nio??<br>
     * </p>
     * 
     * <p>
     * ??,<br>
     * ?,,??? ????cpu,?cpu? <br>
     * ? Java IO ,? IO,NIO ?? IO
     * </p>
     * 
     * <p>
     * The new I/O (NIO) APIs introduced in v 1.4 provide new features and improved performance in the areas of buffer management, scalable
     * network and file I/O, character-set support, and regular-expression matching. The NIO APIs supplement the I/O facilities in the
     * java.io package.
     * </p>
     * 
     * <p>
     * The NIO APIs include the following features:
     * </p>
     * 
     * <ol>
     * <li>Buffers for data of primitive types</li>
     * <li>Character-set encoders and decoders</li>
     * <li>A pattern-matching facility based on Perl-style regular expressions</li>
     * <li>Channels, a new primitive I/O abstraction</li>
     * <li>A file interface that supports locks and memory mapping</li>
     * <li>A multiplexed, non-blocking I/O facility for writing scalable servers</li>
     * </ol>
     * </blockquote>
     * 
     * <p>
     * As creme de la creme with regard to performance,you could use NIO {@link java.nio.channels.Channels} and {@link java.nio.ByteBuffer}.
     * </p>
     *
     * @param bufferLength
     *            the buffer length
     * @param inputStream
     *            the input stream
     * @param outputStream
     *            the output stream
     * @since 1.0.8
     * @since jdk1.4
     */
    private static void writeUseNIO(int bufferLength, InputStream inputStream, OutputStream outputStream) {
        Date beginDate = new Date();
        ReadableByteChannel readableByteChannel = Channels.newChannel(inputStream);
        WritableByteChannel writableByteChannel = Channels.newChannel(outputStream);
        ByteBuffer byteBuffer = ByteBuffer.allocate(bufferLength);

        try {
            int loopCount = 0;
            int sumSize = 0;
            while (readableByteChannel.read(byteBuffer) != -1) {
                byteBuffer.flip();
                sumSize += writableByteChannel.write(byteBuffer);
                byteBuffer.clear();
                loopCount++;
            }
            if (LOGGER.isDebugEnabled()) {
                String formatSize = FileUtil.formatSize(sumSize);
                String time = DateExtensionUtil.getIntervalForView(beginDate, new Date());
                LOGGER.debug("Write data over,sumSize:[{}],bufferLength:[{}],loopCount:[{}],time:{}", formatSize,
                        bufferLength, loopCount, time);
            }
        } catch (IOException e) {
            throw new UncheckedIOException(e);
        } finally {
            IOUtils.closeQuietly(outputStream);
            IOUtils.closeQuietly(writableByteChannel);
            IOUtils.closeQuietly(inputStream);
            IOUtils.closeQuietly(readableByteChannel);
        }
    }
}