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