Java—IO流 位元組流

来源:http://www.cnblogs.com/tianxintian22/archive/2017/05/09/6821267.html
-Advertisement-
Play Games

IO流(輸入流、輸出流),又分為位元組流、字元流。 流是磁碟或其它外圍設備中存儲的數據的源點或終點。 輸入流:程式從輸入流讀取數據源。數據源包括外界(鍵盤、文件、網路…),即是將數據源讀入到程式的通信通道。 輸出流:程式向輸出流寫入數據。將程式中的數據輸出到外界(顯示器、印表機、文件、網路…)的通信通 ...


  IO流(輸入流、輸出流),又分為位元組流、字元流。

  流是磁碟或其它外圍設備中存儲的數據的源點或終點。

  輸入流:程式從輸入流讀取數據源。數據源包括外界(鍵盤、文件、網路…),即是將數據源讀入到程式的通信通道。

  輸出流:程式向輸出流寫入數據。將程式中的數據輸出到外界(顯示器、印表機、文件、網路…)的通信通道。

  • 位元組流

  1.InputStream、OutputStream

  InputStream抽象了應用程式讀取數據的方式

  OutputStream抽象了應用程式寫出數據的方式

  2.讀到文件結尾,稱為EOF = end,讀到-1就讀到結尾

  3.輸入流基本方法

  int b = in.read();讀取一個位元組,無符號填充到int的低八位.-1是EOF

  int.read(byte[] buf)讀取數據填充到位元組數組buf

  int.read(byte[] buf, int start, int size)讀取數據填充到位元組數組buf,從buf的start位置開始存儲size長度的數據

  4.輸出流基本方法

  out.write(int b);寫出一個byte到流,b的低八位

  out.write(byte[] buf);將buf位元組數組都寫入到流

  out.write(byte[] buf, int start, int size);位元組數組buf從start位置開始寫size長度的位元組到流

  5.FileInputStream是InputStream的子類,具體實現了在文件上讀取數據 

    6.FileOutputStream是OutputStream的子類,實現了向文件中寫出位元組數據的方法

  FileInputStream的demo:

package com.test.io;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class IOUtils {
    /**
     * 讀取指定文件內容,按照十六進位輸出到控制台
     * 並且每輸出10個byte換行
     * @param fileName
     * @throws IOException
     */
    public static void printHex(String fileName) throws IOException {
        //把文件作為位元組流進行讀操作
        FileInputStream in = new FileInputStream(fileName);
        int b;
        int i = 1;
        while ((b = in.read()) != -1) {
            if (b <= 0xf) {
                System.out.print("0");
            }
            System.out.print(Integer.toHexString(b) + "  ");
            if (i % 10 == 0) {
                System.out.println("");
            }
            i++;
        }
        in.close();
    }

    public static void printHexByByteArray(String fileName) throws IOException {
        FileInputStream in = new FileInputStream(fileName);
        byte[] buf = new byte[20*1024];
        
        //如果位元組數組夠大,可以一次性讀完
        //從in中批量讀取位元組,放入到buf這個位元組數組中,從第0個位置開始放,最多放buf.length個,返回的是讀到的位元組的個數
        /* int bytes = in.read(buf, 0, buf.length);
        int j = 1;
        for(int i = 0;i < bytes; i++) {
            if (buf[i] <= 0xf) {
                System.out.print("0");
            }
            System.out.print(Integer.toHexString(buf[i] & 0xff) + "  ");
            if (j % 10 == 0) {
                System.out.println("");
            }
            j++;
        } */
        
        //如果位元組數組不夠大,不能一次性讀完
        int bytes = 0;
        int j = 1;
        while ((bytes = in.read(buf, 0, buf.length)) != -1) {
            for (int i = 0; i <bytes; i++) {
                if (buf[i] <= 0xf) {
                    System.out.print("0");
                }
                System.out.print(Integer.toHexString(buf[i] & 0xff) + "  ");
                if (j % 10 == 0) {
                    System.out.println("");
                }
                j++;
            }
        }
    }

}

  FileOutputStream的demo:

package com.test.io;

import java.io.FileOutputStream;
import java.io.IOException;

public class FileOutputDemo {

    public static void main(String[] args) throws IOException {
        //如果該文件不存在,則直接創建,如果存在,刪除後創建。(如果第二個參數為 true,則將位元組寫入文件末尾處,而不是寫入文件開始處。)
        FileOutputStream out = new FileOutputStream("F:\\javaio\\out.dat");
        out.write('A');//寫入了‘A’的低八位(一次只寫入一個位元組)
        int a = 10;
        out.write(a >>> 24);
        out.write(a >>> 16);
        out.write(a >>> 8);
        out.write(a);
        
        byte[] b = "10".getBytes();
        out.write(b);
        
        out.close();
        
        IOUtils.printHex("F:\\javaio\\out.dat");        
    }
}

  7.DataOutputStream和DataInputStream,對流功能的擴展,可以更加方便的讀取int,long,字元等類型數據。

package com.test.io;

import java.io.DataOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class DataOutputDemo {

    public static void main(String[] args) throws IOException {
        String file = "F:\\javaio\\b.txt";
        DataOutputStream dos = new DataOutputStream(new FileOutputStream(file));
        dos.writeInt(10);
        dos.writeInt(-10);
        dos.writeLong(10l);
        dos.writeDouble(10.5);
        dos.writeUTF("你好");
        dos.writeChars("中國");
        dos.close();
        IOUtils.printHex(file);
    }
}

  運行結果:

00  00  00  0a  ff  ff  ff  f6  00  00  
00  00  00  00  00  0a  40  25  00  00  
00  00  00  00  00  06  e4  bd  a0  e5  
a5  bd  4e  2d  56  fd  

  其中,00 06兩個位元組是“你好”這兩個中文的位元組個數。

package com.test.io;

import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.IOException;

public class DataInputDemo {

    public static void main(String[] args) throws IOException {
        String file = "F:\\javaio\\b.txt";
        DataInputStream dis = new DataInputStream(new FileInputStream(file));
        int i = dis.readInt();
        System.out.println(i);
        i = dis.readInt();
        System.out.println(i);
        long l = dis.readLong();
        System.out.println(l);
        double d = dis.readDouble();
        System.out.println(d);
        String s = dis.readUTF();
        System.out.println(s);
        dis.close();
    }

}

  運行結果:

10
-10
10
10.5
你好

   8.BufferedInputStream&BufferedOutputStream,這兩個流類為IO提供了帶緩衝區的操作,一般打開文件進行寫入或讀取操作時,都會加上緩衝,這種流模式提高了IO的性能。

  文件的拷貝:

package com.test.io;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class IOUtils {/**
     * 拷貝文件,位元組批量讀取
     * @param srcFile 源文件
     * @param destFile 目標文件
     * @throws IOException
     */
    public static void copyFile(File srcFile, File destFile) throws IOException {
        if (!srcFile.exists()) {
            throw new IllegalArgumentException("文件" + srcFile + "不存在");
        }
        if (!srcFile.isFile()) {
            throw new IllegalArgumentException(srcFile + "不是文件");
        }
        FileInputStream in = new FileInputStream(srcFile);
        FileOutputStream out = new FileOutputStream(destFile);
        byte[] buf = new byte[10*1024];
        int b;
        while ((b = in.read(buf, 0, buf.length)) != -1) {
            out.write(buf,0,b);
            out.flush();//最好加上,刷新此輸出流並強制寫出所有緩衝的輸出位元組。
        }
        in.close();
        out.close();
    }
    /**
     * 拷貝文件,利用帶緩衝的位元組流
     * @param srcFile
     * @param destFile
     * @throws IOException
     */
    public static void copyFileByBuffer(File srcFile, File destFile) throws IOException {
        if (!srcFile.exists()) {
            throw new IllegalArgumentException("文件" + srcFile + "不存在");
        }
        if (!srcFile.isFile()) {
            throw new IllegalArgumentException(srcFile + "不是文件");
        }
        FileInputStream in = new FileInputStream(srcFile);
        FileOutputStream out = new FileOutputStream(destFile);
        
        BufferedInputStream bis = new BufferedInputStream(in);
        BufferedOutputStream bos = new BufferedOutputStream(out);
        
        int c;
        while ((c = bis.read()) != -1) {
            bos.write(c);
            bos.flush();
        }
        
        bis.close();
        bos.close();
    }
    /**
     * 拷貝文件,通過單位元組讀取
     * @param srcFile
     * @param destFile
     * @throws IOException
     */
    public static void copyFileByByte(File srcFile, File destFile) throws IOException {
        if (!srcFile.exists()) {
            throw new IllegalArgumentException("文件" + srcFile + "不存在");
        }
        if (!srcFile.isFile()) {
            throw new IllegalArgumentException(srcFile + "不是文件");
        }
        FileInputStream in = new FileInputStream(srcFile);
        FileOutputStream out = new FileOutputStream(destFile);
        
        int c;
        while ((c = in.read()) != -1) {
            out.write(c);
            out.flush();
        }
        
        in.close();
        out.close();
    }
}

  測試文件拷貝:

package com.test.io;

import java.io.File;
import java.io.IOException;

public class IOUtilsTest {

    public static void main(String[] args) {
        //IOUtils.printHex("D:\\javaProgram\\Hello.java");
        try {
            long start = System.currentTimeMillis();
            //IOUtils.copyFile(new File("F:\\javaio\\1.mp3"), new File("F:\\javaio\\2.mp3"));//211ms
            //IOUtils.copyFileByBuffer(new File("F:\\javaio\\1.mp3"), new File("F:\\javaio\\3.mp3"));//18583ms
            IOUtils.copyFileByByte(new File("F:\\javaio\\1.mp3"), new File("F:\\javaio\\4.mp3"));//37822ms
            long end = System.currentTimeMillis();
            System.out.println(end - start);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

  根據以上測試看出,文件拷貝,最快的方式是通過位元組的批量讀取。

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 棧(Stack)和隊列是非常類似的一個容器,只是棧是一個後進先出(LIFO)的容器。 棧用Push()方法在棧中添加元素,用Pop()方法獲取最近添加的一個元素: Stack<T>與Queue<T>類(http://www.cnblogs.com/afei-24/p/6829817.html)類似, ...
  • 隊列是其元素按照先進先出(FIFO)的方式來處理的集合。 隊列使用System.Collections.Generic名稱空間中的泛型類Queue<T>實現。在內部,Queue<T>類使用T類型的數組,這類似List<T>(http://www.cnblogs.com/afei-24/p/68247 ...
  • 查看原文 本文我們來學習 Code first 在初始化資料庫時是如何決定資料庫名稱和伺服器的。 下圖展示了資料庫初始化的工作流。 由圖可知,上下文類的基本構造函數的參數可以有以下幾種方式: 1、沒有參數 2、有資料庫名 3、有連接字元串名 一、沒有參數(No Parameter) 如果上下文類的基 ...
  • 總目錄 插件目錄結構(一) Admin後臺頁面編寫(二) 前臺模板頁編寫(三) URL重寫(四) 本實例旨在以一個實際的項目中的例子來介紹如何在dtcms中製作插件,本系列文章非入門教程,部分邏輯實現一帶而過,敬請諒解。 時隔2年,再次收到本文的回覆,實在慚愧,本系列竟然終止於第二章節。不從外部找原... ...
  • 模塊:用一堆代碼實現了某個功能的代碼集合,模塊是不帶 .py 擴展的另外一個 Python 文件的文件名。 一、time & datetime模塊 二、random模塊 三、OS模塊 四、sys模塊 五、shutil模塊 六、XML處理模塊 七、configparser模塊 用於生成和修改常見配置文 ...
  • 03 樹1:樹的同構 Description: 給定兩棵樹T1和T2。如果T1可以通過若幹次左右孩子互換就變成T2,則我們稱兩棵樹是“同構”的。例如圖1給出的兩棵樹就是同構的,因為我們把其中一棵樹的結點A、B、G的左右孩子互換後,就得到另外一棵樹。而圖2就不是同構的。現給定兩棵樹,請你判斷它們是否是 ...
  • 前面有用 tomcat-redis-session-manager來實現分散式session管理,但是它有一定的局限性,主要是跟tomcat綁定太緊了,這裡改成用Spring Session來管理分散式session,Spring Session就完全實現了與具體的容器無關,如果需要瞭解如何用tom ...
  • 1、使用ext_skel工具生成擴展框架 ./ext_skel --extname=myext 2、編輯config.m4文件 cd myext/vim config.m4 3、php化並配置phpize5 ./configure --with-php-config=/usr/bin/php-con ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...