该类从名字看就是IO工具类。
同样类声明为final,构造为private,方法都是static。这些是工具类的标配呀!
源码:
/** * Provides I/O operations * * @author Sergey Tarasevich (nostra13[at]gmail[dot]com) * @since 1.0.0 */ public final class IoUtils { /** {@value} */ public static final int DEFAULT_BUFFER_SIZE = 32 * 1024; // 32 KB,默认的文件缓存 /** {@value} */ public static final int DEFAULT_IMAGE_TOTAL_SIZE = 500 * 1024; // 500 Kb,默认的图片文件缓存 /** {@value} */ public static final int CONTINUE_LOADING_PERCENTAGE = 75;//继续下载阈值(75%),就是当已经下载了超过75%的时候,就不能够取消了。 private IoUtils() { } /** * Copies stream, fires progress events by listener, can be interrupted by listener. Uses buffer size = * {@value #DEFAULT_BUFFER_SIZE} bytes. * * @param is Input stream * @param os Output stream * @param listener null-ok; Listener of copying progress and controller of copying interrupting * @return <b>true</b> - if stream copied successfully; <b>false</b> - if copying was interrupted by listener * @throws IOException */ public static boolean copyStream(InputStream is, OutputStream os, CopyListener listener) throws IOException { return copyStream(is, os, listener, DEFAULT_BUFFER_SIZE); } /** * Copies stream, fires progress events by listener, can be interrupted by listener. * * @param is Input stream * @param os Output stream * @param listener null-ok; Listener of copying progress and controller of copying interrupting * @param bufferSize Buffer size for copying, also represents a step for firing progress listener callback, i.e. * progress event will be fired after every copied <b>bufferSize</b> bytes * @return <b>true</b> - if stream copied successfully; <b>false</b> - if copying was interrupted by listener * @throws IOException */ public static boolean copyStream(InputStream is, OutputStream os, CopyListener listener, int bufferSize) throws IOException {//从is读到os中,中间支持中断,而是否中断通过shouldStopLoading函数进行判断 int current = 0; int total = is.available(); if (total <= 0) { total = DEFAULT_IMAGE_TOTAL_SIZE; } final byte[] bytes = new byte[bufferSize]; int count; if (shouldStopLoading(listener, current, total)) return false; while ((count = is.read(bytes, 0, bufferSize)) != -1) { os.write(bytes, 0, count); current += count; if (shouldStopLoading(listener, current, total)) return false; } os.flush(); return true; } private static boolean shouldStopLoading(CopyListener listener, int current, int total) { if (listener != null) { boolean shouldContinue = listener.onBytesCopied(current, total);//listener跟据当前下载的量判断是否正确 if (!shouldContinue) {//当认为下载错误的时候,我们要判断是否中断 if (100 * current / total < CONTINUE_LOADING_PERCENTAGE) {//如果下载了不到75%则应该中断 return true; // if loaded more than 75% then continue loading anyway } } } return false; } /** * Reads all data from stream and close it silently * * @param is Input stream */ public static void readAndCloseStream(InputStream is) { final byte[] bytes = new byte[DEFAULT_BUFFER_SIZE]; try { while (is.read(bytes, 0, DEFAULT_BUFFER_SIZE) != -1); } catch (IOException ignored) { } finally { closeSilently(is); } } public static void closeSilently(Closeable closeable) { if (closeable != null) { try { closeable.close(); } catch (Exception ignored) { } } } /** Listener and controller for copy process */ public static interface CopyListener { /** * @param current Loaded bytes * @param total Total bytes for loading * @return <b>true</b> - if copying should be continued; <b>false</b> - if copying should be interrupted */ boolean onBytesCopied(int current, int total); } }