摘要:流按操作類型分為兩種字節流字節流可以操作任何數據因為在計算機中任何數據都是以字節的形式存儲的字符流字符流只能操作純字符數據,比較方便。
1_IO流概述及其分類
1.概念
IO流用來處理設備之間的數據傳輸
Java對數據的操作是通過流的方式
Java用于操作流的類都在IO包中
流按流向分為兩種:輸入流,輸出流。
流按操作類型分為兩種:
字節流 : 字節流可以操作任何數據,因為在計算機中任何數據都是以字節的形式存儲的
字符流 : 字符流只能操作純字符數據,比較方便。
2.IO流常用父類
字節流的抽象父類:
InputStream
OutputStream
字符流的抽象父類:
Reader
Writer
3.IO程序書寫
使用前,導入IO包中的類
使用時,進行IO異常處理
使用后,釋放資源
2_FileInputStreamread()一次讀取一個字節
import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; public class Demo1_FileInputStream { public static void main(String[] args) throws IOException { // demo1(); FileInputStream fis = new FileInputStream("xxx.txt"); //創建一個文件輸入流對象,并關聯xxx.txt int b; //定義變量,記錄每次讀到的字節 while((b = fis.read()) != -1) { //將每次讀到的字節賦值給b并判斷是否是-1 System.out.println(b); //打印每一個字節 } fis.close(); //關閉流釋放資源 } private static void demo1() throws FileNotFoundException, IOException { FileInputStream fis = new FileInputStream("xxx.txt");//創建流對象 int x = fis.read(); //從硬盤上讀取一個字節 System.out.println(x); int y = fis.read(); System.out.println(y); int z = fis.read(); System.out.println(z); int a = fis.read(); System.out.println(a); int b = fis.read(); System.out.println(b); fis.close(); //關流釋放資源 } }3_read()方法返回值為什么是int
read()方法讀取的是一個字節,為什么返回是int,而不是byte
字節輸入流可以操作任意類型的文件,比如圖片音頻等,這些文件底層都是以二進制形式的存儲的,如果每次讀取都返回byte,會有可能在讀到111111111,而11111111是byte類型的-1,程序在遇到-1就會停止讀取,用int類型接收遇到11111111會在其前面補上24個0湊足4個字節,那么byte類型的-1就變成int類型的255了,這樣可以保證整個數據讀完,而結束標記的-1是int類型的。
4_FileOutputStreamwrite()一次寫出一個字節
import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; public class Demo2_FileOutputStream { public static void main(String[] args) throws IOException { FileOutputStream fos = new FileOutputStream("yyy.txt"); //自動創建沒有的對象 fos.write(97); //雖然寫出的是一個int數,但是到文件上的是一個字節,會自動去除前三個八位 fos.write(98); fos.write(99); fos.close(); } }5_FileOutputStream追加
A:案例演示
public static void main(String[] args) throws IOException { // demo1(); FileOutputStream fos = new FileOutputStream("yyy.txt",true);//追加在第二個參數傳true fos.write(97); fos.write(98); fos.close(); }6_拷貝圖片
FileInputStream讀取
FileOutputStream寫出
import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; public class Demo3_Copy { public static void main(String[] args) throws IOException { // demo1(); FileInputStream fis = new FileInputStream("視頻.avi"); //創建輸入流對象,關聯視頻 FileOutputStream fos = new FileOutputStream("copy.avi"); //創建輸出流對象,關聯copy.avi int b; while((b = fis.read()) != -1) { //在不斷讀取每個字節 fos.write(b); //將每一個字節寫出 } fis.close(); //關流釋放資源 fos.close(); } private static void demo1() throws FileNotFoundException, IOException { FileInputStream fis = new FileInputStream("圖片1.png"); //創建輸入流對象,關聯圖片 FileOutputStream fos = new FileOutputStream("copy.jpg"); //創建輸出流對象,關聯cop.jpg int b; while((b = fis.read()) != -1) { //在不斷讀取每個字節 fos.write(b); //將每一個字節寫出 } fis.close(); //關流釋放資源 fos.close(); } }7_拷貝音頻文件畫原理圖
A:案例演示
字節流一次讀寫一個字節復制音頻
弊端:效率太低
8_字節數組拷貝之available()方法
A:案例演示
int read(byte[] b):一次讀取一個字節數組
write(byte[] b):一次寫出一個字節數組
available()獲取讀的文件所有的字節個數
弊端:有可能會內存溢出
import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; public class Demo3_Copy { public static void main(String[] args) throws IOException { //第二種拷貝,不推薦,有可能導致內存溢出 FileInputStream fis = new FileInputStream("視頻.avi"); //創建輸入流對象,關聯視頻 FileOutputStream fos = new FileOutputStream("copy.avi"); //創建輸出流對象,關聯copy.avi // int len = fis.available(); // System.out.println(len); byte[] arr = new byte[fis.available()]; //創建與文件一樣大小的字節數組 fis.read(arr); //將文件上的字節讀取到內存中 fos.write(arr); //將字節數組中的字節數據寫到文件上 fis.close(); fos.close(); } }9_定義小數組
write(byte[] b)
write(byte[] b, int off, int len)寫出有效的字節個數
import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; public class Demo4_ArrayCopy { public static void main(String[] args) throws IOException { // demo1(); FileInputStream fis = new FileInputStream("xxx.txt"); FileOutputStream fos = new FileOutputStream("yyy.txt"); byte[] arr = new byte[2]; int len; while((len = fis.read(arr)) != -1) { fos.write(arr,0,len); } fis.close(); fos.close(); } private static void demo1() throws FileNotFoundException, IOException { FileInputStream fis = new FileInputStream("xxx.txt"); byte[] arr = new byte[2]; int a = fis.read(arr); //將文件上的字節讀取到字節數組中 System.out.println(a); //讀到的有效字節個數 for (byte b : arr) { //第一次獲取到文件上的a和b System.out.println(b); } System.out.println("----"); int c = fis.read(arr); System.out.println(c); for (byte b : arr) { System.out.println(b); } fis.close(); } }10_定義小數組的標準格式
A:案例演示
字節流一次讀寫一個字節數組復制圖片和視頻
public static void main(String[] args) throws IOException { FileInputStream fis = new FileInputStream("視頻.avi"); FileOutputStream fos = new FileOutputStream("copy.avi"); byte[] arr = new byte[1024 * 8]; int len; while((len = fis.read(arr)) != -1) { //忘記寫arr,返回的是碼表值 fos.write(arr,0,len); } fis.close(); fos.close(); }11_BufferedInputStream和BufferOutputStream拷貝
A:緩沖思想
字節流一次讀寫一個數組的速度明顯比一次讀寫一個字節的速度快很多,
這是加入了數組這樣的緩沖區效果,java本身在設計的時候,
也考慮到了這樣的設計思想(裝飾設計模式后面講解),所以提供了字節緩沖區流
B.BufferedInputStream
BufferedInputStream內置了一個緩沖區(數組)
從BufferedInputStream中讀取一個字節時
BufferedInputStream會一次性從文件中讀取8192個, 存在緩沖區中, 返回給程序一個
程序再次讀取時, 就不用找文件了, 直接從緩沖區中獲取
直到緩沖區中所有的都被使用過, 才重新從文件中讀取8192個
C.BufferedOutputStream
BufferedOutputStream也內置了一個緩沖區(數組)
程序向流中寫出字節時, 不會直接寫到文件, 先寫到緩沖區中
直到緩沖區寫滿, BufferedOutputStream才會把緩沖區中的數據一次性寫到文件里
D.小數組的讀寫和帶Buffered的讀取哪個更快?
定義小數組如果是8192個字節大小和Buffered比較的話
定義小數組會略勝一籌,因為讀和寫操作的是同一個數組
而Buffered操作的是兩個數組
import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; public class Demo5_BufferCopy { public static void main(String[] args) throws IOException { FileInputStream fis = new FileInputStream("視頻.avi"); //創建輸入流對象 FileOutputStream fos = new FileOutputStream("copy.avi");//創建輸出流對象 //byte[] arr = new byte[8192]; BufferedInputStream bis = new BufferedInputStream(fis);//創建緩沖區對象,對輸入流進行包裝,讓其變得更強 BufferedOutputStream bos = new BufferedOutputStream(fos); int b; while((b = bis.read()) != -1) { bos.write(b); } bis.close(); bos.close(); } }12_flush和close方法的區別
flush()方法
用來刷新緩沖區的,刷新后可以再次寫出
close()方法
用來關閉流釋放資源的的,如果是帶緩沖區的流對象的close()方法,不但會關閉流,還會再關閉流之前刷新緩沖區,關閉后不能再寫出
public static void main(String[] args) throws IOException { BufferedInputStream bis = new BufferedInputStream(new FileInputStream("視頻.avi")); BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("copy.mp3")); int b; while((b = bis.read()) != -1) { bos.write(b); bos.flush(); } // bos.close(); // bis.close(); }13_字節流讀寫中文)
字節流讀取中文的問題
字節流在讀中文的時候有可能會讀到半個中文,造成亂碼
字節流寫出中文的問題
字節流直接操作的字節,所以寫出中文必須將字符串轉換成字節數組
寫出回車換行 write("rn".getBytes());
import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; public class Demo6_Chinese { public static void main(String[] args) throws IOException { // demo1(); FileOutputStream fos = new FileOutputStream("zzz.txt"); fos.write("同九年,汝獨秀".getBytes()); fos.write(" ".getBytes()); fos.close(); } private static void demo1() throws FileNotFoundException, IOException { FileInputStream fis = new FileInputStream("yyy.txt"); byte[] arr = new byte[4]; int len; while((len = fis.read(arr)) != -1) { System.out.println(new String(arr,0,len)); } fis.close(); } }14_流的標準處理異常代碼1.6版本及其以前
try finally嵌套
import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; public class Demo7_TryFinally { public static void main(String[] args) throws IOException { FileInputStream fis = null; FileOutputStream fos = null; try { fis = new FileInputStream("xxx.txt"); fos = new FileOutputStream("yyy.txt"); int b; while((b = fis.read()) != -1) { fos.write(b); } }finally { try { if(fis != null) fis.close(); }finally { //try fianlly的目的是盡量關閉 if(fos != null) fos.close(); } } } }15_流的標準處理異常代碼1.7版本
try close
原理
在try()中創建的流對象必須實現了AutoCloseable這個接口,如果實現了,在try后面的{}(讀寫代碼)執行后就會自動調用,流對象的close方法將流關掉
import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; public class Demo7_TryFinally { public static void main(String[] args) throws IOException { try( FileInputStream fis = new FileInputStream("xxx.txt"); FileOutputStream fos = new FileOutputStream("yyy.txt"); MyClose mc = new MyClose(); ){ int b; while((b = fis.read()) != -1) { fos.write(b); } } } } class MyClose implements AutoCloseable{ //實現AutoCloseable,自動調用close(); public void close() { System.out.println("我關了"); } }16_圖片加密
給圖片加密
import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; public class Demo8_test { public static void main(String[] args) throws IOException { BufferedInputStream bis = new BufferedInputStream(new FileInputStream("圖片1.jpg")); BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("copy.jpg")); int b; while((b = bis.read()) != -1) { bos.write(b ^ 123);//將寫出的字節異或上一個數,這個數就是秘鑰,解密再異或就行 } bis.close(); bos.close(); } }17_拷貝文件
在控制臺錄入文件的路徑,將文件拷貝到當前項目下
import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.util.Scanner; public class Demo9_test { public static void main(String[] args) throws IOException { File file = getFile(); //獲取文件 BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file)); BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file.getName())); int b; while((b = bis.read()) != -1) { bos.write(b); } bis.close(); bos.close(); } //定義一個方法獲取鍵盤錄入的文件路徑,并封裝成file對象返回 //返回值類型:File 參數列表:無 public static File getFile() { Scanner sc = new Scanner(System.in);//創建鍵盤錄入對象 System.out.println("請輸入一個文件的路徑:"); while(true) { String line = sc.nextLine(); //接收鍵盤錄入的路徑 File file = new File(line); //封裝成File對象,并對其判斷 if(!file.exists()) { System.out.println("您錄入的文件路勁不存在,請重新錄入:"); }else if(file.isDirectory()) { System.out.println("您錄入的是文件夾路徑,請重新錄入:"); }else { return file; //彈棧返回路徑 } } } }18_錄入數據拷貝到文件
將鍵盤錄入的數據拷貝到當前項目下的text.txt文件中,鍵盤錄入數據當遇到quit時就退出
import java.io.FileOutputStream; import java.io.IOException; import java.util.Scanner; public class Demo10_test { public static void main(String[] args) throws IOException { Scanner sc = new Scanner(System.in); //創建鍵盤錄入對象 FileOutputStream fos = new FileOutputStream("text.txt");//創建輸出流對象,關聯text.txt文件 System.out.println("請輸入數據:"); while(true) { String line = sc.nextLine(); //將鍵盤錄入的數據存儲在line中 if("quit".equals(line)) { break; //遇到quit退出循環 } fos.write(line.getBytes()); //字符串寫出必須轉換成字節數組 fos.write(" ".getBytes()); } fos.close(); } }
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/77311.html
摘要:在包下主要包括輸入輸出兩種流,每種輸入輸出流又可分為字節流和字符流兩大類。輸入輸出是從程序運行所在的內存的角度而言的。的輸入流主要由和作為基類,而輸出流主要由和作為基類。 本章主要參考和摘自瘋狂java講義上面的(java編程思想的后面看過后有新的內容再補充進去吧)。 輸入輸出是所有程序都必需的部分————使用輸入機制允許程序讀取外部數據(包括磁盤、光盤等存儲設備上的數據和用戶輸入的...
摘要:基礎知識復習后端掘金的作用表示靜態修飾符,使用修飾的變量,在中分配內存后一直存在,直到程序退出才釋放空間。將對象編碼為字節流稱之為序列化,反之將字節流重建成對象稱之為反序列化。 Java 學習過程|完整思維導圖 - 后端 - 掘金JVM 1. 內存模型( 內存分為幾部分? 堆溢出、棧溢出原因及實例?線上如何排查?) 2. 類加載機制 3. 垃圾回收 Java基礎 什么是接口?什么是抽象...
摘要:一面試題及剖析今日面試題今天壹哥帶各位復習一塊可能會令初學者比較頭疼的內容,起碼當時讓我很有些頭疼的內容,那就是流。在這里壹哥會從兩部分展開介紹流,即與流。除此之外盡量使用字節流。關閉此輸入流并釋放與流相關聯的任何系統資源。 一. 面試題及剖析 1. 今日面試題 今天 壹哥 帶各位復習一塊可...
摘要:除非文件用自帶的記事本打開我們能夠讀懂,才采用字符流,否則建議使用字節流。 第四階段 IO IO流 前言: 前面的學習我們只能夠在已有的一定封閉范圍內進行一些操作,但是這顯然是無趣的,也是不支持我們實現一些復雜的需求,所以Java提供IO流這樣一種概念,方便我們對數據進行操作 而使用IO流我們可以實現一些強大的功能,例如針對文件的移動復制等操作,又或者程序與外部文件之間的數據存儲或者讀...
閱讀 2802·2021-09-01 10:30
閱讀 1691·2019-08-30 15:52
閱讀 980·2019-08-29 18:40
閱讀 1135·2019-08-28 18:30
閱讀 2406·2019-08-23 17:19
閱讀 1334·2019-08-23 16:25
閱讀 2713·2019-08-23 16:18
閱讀 2990·2019-08-23 13:53