IO流 四、字節流

  • 編碼問題
  • File類的使用
  • RandomAccessFile
  • 字節流
  • 字符流
  • 對象的序列化和反序列化

4-1 字節流之文件輸入流FileInputStrream-1

IO流(輸入流、輸出流)

字節流、字符流

1.字節流

1)InputStream、OputStream

  • InputStream抽象了應用程序讀取數據的方式
  • OutputStream抽象了應用程序寫出輸出的方式

2)EOF = End 讀到-1就讀到了結尾

3)輸入流基本方法

int b = in.read();  //讀取一個字節無符號填充到int的低8位,-1是 EOF

in.read(byte[] buf) ; //讀取數據填充到字節數組buf

in.read(byte[] buf, int start, int size);  // 讀取數據到字節數組buf 從buf的start位置開始 存放size長度的數據

4)輸出流基本方法

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

out.write(byte[] buf);  // 將bnf字節數組都寫入到流

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

5)FileInputStream--->具體實現了在文件上讀取數據

package com.io;

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

public class IOUtil {
    /**
     * 讀取指定文件內容,按照16進制輸出到控制檯 並且每輸出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) {
                // 單位數前面補0
                System.out.print("0");
            }
            System.out.print(Integer.toHexString(b) + "  "); // 將整型b轉換爲16進製表示的字符串
            if (i++ % 10 == 0) {
                System.out.println();
            }
        }
        in.close();
    }

}
 

 

4-2 字節流之文件輸入流FileInputStrream-2

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]) + "  "); if (j++ %10 == 0) {
         * System.out.println(); } }
         */
        // 當字節數組不夠大,一次性讀不完時,怎麼辦
        int bytes = 0;
        int j = 1;
        while ((bytes = in.read(buf, 0, buf.length)) != -1) {
            for (int i = 0; i < buf.length; i++) {
                // byte類型8位,int類型32位,爲了避免數據轉換錯誤,通過0xff將高24位清零
                System.out.print(Integer.toHexString(buf[i] & 0xff) + "  ");
                if (j++ % 10 == 0) {
                    System.out.println();
                }
            }
        }
    }

 

4-3 字節流之文件輸出流FileOutputStream

FileOutputStream 實現了向文件中寫出byte數據的方法

package com.io;

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

public class FileOutDemo {

    public static void main(String[] args) throws IOException {
        // 如果該文件不存在,則直接創建;如果存在,刪除後創建
        FileOutputStream out = new FileOutputStream("demo/out.dat");
        // 要追加內容,第二個參數寫true,否則文件將被清空
        out.write('A'); // 寫出了'A'的低8位
        out.write('B'); // 寫出了'B'的第8位
        int a = 10; // write 只能寫8位,那麼寫一個int需要寫4次每次8位
        out.write(a >>> 24);
        out.write(a >>> 16);
        out.write(a >>> 8);
        out.write(a);
        byte[] gbk = "中國".getBytes("gbk");
        out.write(gbk);
        out.close();

        IOUtil.printHex("demo/out.dat");

    }

}

文件複製

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[8 * 1024];
        int b;
        while ((b = in.read(buf, 0, buf.length)) != -1) {
            out.write(buf, 0, b);
            out.flush(); // 最好加上
        }
        in.close();
        out.close();
    }

 

4-4 字節流之數據輸入輸出流

DataOutputStream/DateOutputStream

對“流”的功能的擴展,可以更加方便的讀取int,long,字符等類型的數據

DateOutputStream

writeInt()/wirteDouble()/writeUTF()

 

package com.io;

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

public class DosDemo {

    public static void main(String[] args) throws IOException {

        String file = "demo/dos.dat";
        DataOutputStream dos = new DataOutputStream(new FileOutputStream(file));
        dos.writeInt(10);
        dos.writeInt(-10);
        dos.writeLong(10l);
        dos.writeDouble(10.5);
        // 採用utf-8編碼寫出
        dos.writeUTF("中國");
        // 採用utf-16be編碼寫出
        dos.writeChars("中國");
        dos.close();
        IOUtil.printHex(file);
    }

}
 

package com.io;

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

public class DisDemo {

    public static void main(String[] args) throws IOException {
        String file = "demo/dos.dat";
        IOUtil.printHex(file);
        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 b = dis.readDouble();
        System.out.println(b);
        String s = dis.readUTF();
        System.out.println(s);
        dis.close();
    }

}
 

 

4-5 字節流緩衝

BufferedInputStream & BufferedOutputStream

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

從應用程序中把數據放入文件,就相當於將一缸水導入到另一個缸中:

FileOutputStream--->wirte()方法相當於一滴一滴地把水“轉移”過去

DataOutputStream--->wirteXXX()方法會方便一些,相當於一瓢一瓢把水“”轉移“”

BufferedOutputStream--->wirte()方法更方便,相當於一瓢一瓢水先放入桶中,再從桶中倒入另一個缸中

/**
     * 進行文件的拷貝,利用帶緩衝的字節流
     * @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 + "不是文件");
        }
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream(srcFile));
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(destFile));
        int c;
        while ((c = bis.read()) != -1) {
            bos.write(c);
            bos.flush();  // 刷新緩衝區
        }
        bis.close();
        bos.close();
    }

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章