<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    posts - 262,  comments - 221,  trackbacks - 0
    【一】Apache commons IO包之IOUtils

    前面我們已經學習了FileUtils,知道了Apache commons IO包提供了很多實用的工具來對文件進行操作。但是它們的底層到底是怎么實現的呢?如果現在我們要操作的不是文件,而是網絡資源呢?

    其實FileUtils的基石就是IOUtils,它內置了大量的簡化方法來簡化IO讀寫操作和提供默認的緩沖支持。看看官網的說法:



    【二】IOUtils的常用API及解析

    ①讀操作

    IOUtils類提供的讀操作方法有兩大類:第一類是readLines方法。第二類是toXxx方法。

     ※ readLines方法

    List readLines(InputStream input)
    List readLines(InputStream input, String encoding)
    readLines(Reader input)


    我們知道在字節流中是沒有“行”的概念的,但是為什么這里的readLines方法可以接收InputStream呢?看看源代碼就知道了
    public static List readLines(InputStream input, String encoding) throws IOException {
            
    if (encoding == null{
                
    return readLines(input);
            }
     else {
                InputStreamReader reader = new InputStreamReader(input, encoding);

                
    return readLines(reader);
            }

        }


    public static List readLines(Reader input) throws IOException {
            BufferedReader reader 
    = new BufferedReader(input);
            List list 
    = new ArrayList();
            String line 
    = reader.readLine();
            
    while (line != null{
                list.add(line);
                line 
    = reader.readLine();
            }

            
    return list;
        }

    原來在底層,IOUtils使用了InputStreamReader對input stream進行了包裝,到了readLines(Reader)方法內,又再加了一個緩沖。如果我們是直接調用readLines(Reader)方法,為了確保編碼正確,需要手工創建一個InputStreamReader并指明encoding,否則將采用默認的encoding。

     ※ toXxx方法

    IOUtils支持把input stream中的數據轉換成byte[],char[],String對象。而且input stream可以是字節流,字符流。同時可以指定encoding。這些方法實質上是“輸出”的過程:即從輸入流中讀入數據,然后轉換為byte[],char[],String,輸出到內存中。看看下面的一個源代碼:

        public static char[] toCharArray(InputStream is, String encoding)
                
    throws IOException {
            CharArrayWriter output 
    = new CharArrayWriter();
            copy(is, output, encoding);
            
    return output.toCharArray();
        }


        
    public static void copy(InputStream input, Writer output, String encoding)
                
    throws IOException {
            
    if (encoding == null{
                copy(input, output);
            }
     else {
              InputStreamReader in = new InputStreamReader(input, encoding);

                copy(in, output);
            }

        }


        
    public static int copy(Reader input, Writer output) throws IOException {
            
    long count = copyLarge(input, output);
            
    if (count > Integer.MAX_VALUE) {
                
    return -1;
            }

            
    return (int) count;
        }


        
    public static long copyLarge(Reader input, Writer output) throws IOException {
            
    char[] buffer = new char[DEFAULT_BUFFER_SIZE];
            
    long count = 0;
            
    int n = 0;
            
    while (-1 != (n = input.read(buffer))) {
                output.write(buffer, 0, n);

                count 
    += n;
            }

            
    return count;
        }



    我們可以看到這個過程是沒有進行flush的操作的,也就是說使用者必須負責在調用結束后進行緩存清空和輸入、輸入流關閉。對于input stream是文件的情況,在FileUtils的文件讀方法的最后都會調用IOUtils.closeQuietly(in);方法來確保輸入流正確關閉。

    ②寫操作

    和讀操作一樣,IOUtils一樣提供了大量的寫方法,這些方法可以將byte[],char[],StringBuffer,String,Collection中的數據以字節流,字符流的形式寫入到目的源。

     ※ writeLines方法

    public static void writeLines(Collection lines, String lineEnding,
                OutputStream output, String encoding) 
    throws IOException {
            
    if (encoding == null{
                writeLines(lines, lineEnding, output);
            }
     else {
                
    if (lines == null{
                    
    return;
                }

                
    if (lineEnding == null{
                    lineEnding 
    = LINE_SEPARATOR;
                }

                
    for (Iterator it = lines.iterator(); it.hasNext(); ) {
                    Object line 
    = it.next();
                    
    if (line != null{
                        output.write(line.toString().getBytes(encoding));
                    }

                    output.write(lineEnding.getBytes(encoding));
                }

            }

        }


    public static void writeLines(Collection lines, String lineEnding,
                Writer writer) 
    throws IOException {
            
    if (lines == null{
                
    return;
            }

            
    if (lineEnding == null{
                lineEnding 
    = LINE_SEPARATOR;
            }

            
    for (Iterator it = lines.iterator(); it.hasNext(); ) {
                Object line 
    = it.next();
                
    if (line != null{
                    writer.write(line.toString());
                }

                writer.write(lineEnding);
            }

        }

    如果我們查看FileUtils,會發現它對所有的文件讀寫(包括writeLines,writeStringToFile),都是調用字節流+encoding的方式來進行的。因為所有基于字符流的方式最終都需要轉換為基于字節流的方式。

    ③流拷貝

    我們在從文件等數據源讀入數據時,習慣性地以字節讀入,到了內存又轉換成String對象,最后修改性地以字符寫回文件。IOUtils提供了一系列方便的方法來進行這中間的轉換。

    copy(InputStream input, Writer output, String encoding),這個方法使用指定的encoding,從字節流中讀入字節,然后按照encoding解碼,通過字符流寫回目的源。

    copy(Reader input, OutputStream output, String encoding),這個方法從字符流中讀取字符,使用指定的encoding編碼,通過字節流寫回目的源,然后立即清空緩沖。

    上面這兩個方法底層都調用了一個名為copyLarge的方法,他們分別在通過一個byte[]或者char[]數組對要寫回的內容進行緩沖。一次性地從源端讀入4K數據然后通過輸出流寫回。

        public static long copyLarge(InputStream input, OutputStream output)
                
    throws IOException {
            
    byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
            
    long count = 0;
            
    int n = 0;
            
    while (-1 != (n = input.read(buffer))) {
                output.write(buffer, 
    0, n);
                count 
    += n;
            }

            
    return count;
        }


        
    public static long copyLarge(Reader input, Writer output) throws IOException {
            
    char[] buffer = new char[DEFAULT_BUFFER_SIZE];
            
    long count = 0;
            
    int n = 0;
            
    while (-1 != (n = input.read(buffer))) {
                output.write(buffer, 
    0, n);
                count 
    += n;
            }

            
    return count;
        }

    ④內容比較

    這一點在前面FileUtils.contentEquals(File, File)方法中已經有提及,請參考上一篇文章


    -------------------------------------------------------------
    生活就像打牌,不是要抓一手好牌,而是要盡力打好一手爛牌。
    posted on 2010-03-08 21:24 Paul Lin 閱讀(2391) 評論(0)  編輯  收藏 所屬分類: J2SE
    <2010年3月>
    28123456
    78910111213
    14151617181920
    21222324252627
    28293031123
    45678910

    常用鏈接

    留言簿(21)

    隨筆分類

    隨筆檔案

    BlogJava熱點博客

    好友博客

    搜索

    •  

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 亚洲精品无码高潮喷水A片软| 成年女人免费v片| 美女被免费网站视频在线| 亚洲黄色在线视频| 亚洲日韩av无码| 免费一级毛片不卡不收费| 和日本免费不卡在线v| 国产成人AV片无码免费| 日本中文字幕免费看| 亚洲女女女同性video| 亚洲自偷精品视频自拍| 亚洲人成人一区二区三区| 免费很黄很色裸乳在线观看| 成人免费视频88| 久久受www免费人成_看片中文| 久久久久久影院久久久久免费精品国产小说| 免费一级特黄特色大片| 亚洲精品无码高潮喷水A片软| 亚洲五月丁香综合视频| 亚洲国产成人在线视频| 亚洲黄色免费网址| 久久久无码精品亚洲日韩按摩 | 亚洲欧洲自拍拍偷午夜色| 亚洲中文字幕无码爆乳av中文| 免费一级成人毛片| 在线A级毛片无码免费真人| av无码免费一区二区三区| 91嫩草免费国产永久入口| 最近中文字幕2019高清免费| 少妇太爽了在线观看免费视频 | 国产亚洲精品a在线观看 | 一级毛片大全免费播放| 男男gvh肉在线观看免费| 精品久久久久久亚洲中文字幕| jizzjizz亚洲日本少妇| 亚洲精品久久无码| 真人无码作爱免费视频| 特级av毛片免费观看| 又硬又粗又长又爽免费看| 白白色免费在线视频| xxxxx做受大片在线观看免费|