Java—IO流 位元組流,javaio流位元組
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-101010.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(); } }}
根據以上測試看出,檔案拷貝,最快的方式是通過位元組的批量讀取。