標籤:Java基礎 io流 多線程
(一)子節緩衝流
(1) 一次讀取一個位元組數組的方式要比一次讀取一個位元組方式高效.
一次讀取一個位元組數組,相當於構造一個緩衝區,有沒有比一次讀取一個位元組數組還要高效的流?
位元組緩衝流 :
(2)位元組緩衝輸出資料流:
構造方式:
(第一種開發中) public BufferedOutputStream(OutputStream out):採用的預設的緩衝區大小(足夠大了) ,來構造一個位元組緩衝輸出資料流對象
public BufferedOutputStream(OutputStream out,int size):指定size緩衝區大小構造緩衝輸出資料流對象
IllegalArgumentException - 如果 size <= 0
寫資料的方式:
一次寫一個位元組
write(int by)
一次寫一個位元組數組的一部分
write(byte[] b, int off, int len)
(2)位元組緩衝輸入資料流
- public BufferedInputStream(InputStream in):預設緩衝區大小構造緩衝輸入資料流對象
- public BufferedInputStream(InputStream in,int size):指定緩衝區大小構造緩衝輸入資料流對象
- public int read()
- public int read(byte[] b,int off,int len)
在使輸入資料流的時候,
兩種方式讀取(一次讀取一個位元組/一次讀取一個位元組數在),只能用一種方式,否則,會出現錯誤!
(3)電腦如何儲存中文的?
當前平台預設編碼集 :GBK 一個中文兩個位元組
第一個位元組:一定是負數
第二個位元組:一般是負數,可能也會是正數,不會影響的結果.
(4)隱藏檔
IO流:永久儲存(耗時)
資料庫:永久儲存
基本的位元組流
檔案位元組輸入資料流/檔案位元組輸出資料流
高效的位元組流(緩衝流)
StringBuffer:提供了一個字串緩衝區 (可以在緩衝區中不斷追加字串)
(5)編碼和解碼
編碼和解碼:前後的編碼格式要一致!
編碼:
- 簡單理解:將能看懂的東西--->看不懂的東西
- 解碼:
- 看不懂的東西---能看懂的東西
- 舉例: 諜戰片
今天老地方見...
編碼:
今---->位元組---->位元據
解碼:位元據-->十進位資料--->位元組---->字串
今
編碼: 將字串變成一個位元組數組
- public byte[] getBytes() :平台預設編碼集(預設的是Gbk)
- public byte[] getBytes(Charset charset) ;"指定編碼格式
解碼:將位元組數組--->字串
- public String(byte[] bytes) :使用平台預設編碼集(gbk)
- public String(byte[] bytes,Charset charset):用指定的編碼格式來解碼
(二)字元流
(1)使用位元組流一次讀取一個位元組的方式,會造成中文亂碼--->Java提供了一個字元流(專門用來解決中文亂碼問題)
(2 字元輸入資料流:Reader
字元輸出資料流:Writer
- 字元輸出資料流/字元輸入資料流:都是抽象類別
- 使用一個子類:轉換流
字元輸出資料流的構造方法
- public OutputStreamWriter(OutputStream out):使用預設的編碼格式構造一個字元轉換輸出流對象
public OutputStreamWriter(OutputStream out, Charset cs):使用指定編碼格式構造一個字元轉換輸出流對象
轉換流的構成=位元組流+編碼格式(平台預設/指定)
轉換流的對象的建立,格式比較長,非常麻煩,Java--->轉換流的便捷類
Reader:抽象類別:字元輸入資料流
- inputStreamReader(字元轉換輸入流 :inputStream+編碼格式)
便捷類:FileReader,這個類可以直接對檔案進行操作
Writer:抽象類別:字元輸出資料流
- outputStreamWriter(字元轉換輸出流:outputStream+編碼格式)
(3)字元轉換輸入流:InputStreamReader
- InputStreamReader(InputStream in) :構造一個字元轉換輸入流,預設編碼
- public InputStreamReader(InputStream in,Charset cs) 構造一個字元轉換輸入流,指定編碼
字元轉換輸入流=位元組流+編碼格式
(4字元輸入資料流讀資料的方法:
- int read(char[] chs):讀取一個字元數組
- int read():讀取單個字元
(5)字元輸出資料流寫資料的功能:
- public void write(int c):寫單個字元
- public void write(char[] cbuf):寫字元數組
- public abstract void write(char[] cbuf, int off, int len):寫字元數組的一部分
- public void write(String str):寫字串
- public void write(String str,int off, int len):寫字串的某一部分
*flush和close方法的區別?
- close:關閉該流,關閉該流對象以及它關聯 的資源檔,關閉之後,不能再對流對象進行操作了,否則會有異常
- flush:重新整理該流,為了防止一些檔案(圖片檔案/音頻檔案),缺失,或者沒有載入到流對象中,重新整理了該流,還是可以流對象進行操作
字元緩衝輸入資料流/字元緩衝輸出資料流
雜七雜八的流(properties:屬性集合類/合并流/序列化Serializable/記憶體操作流)
(三)字元緩衝流
在字元流中提供了一個更高效的流-->字元緩衝流
- 字元緩衝輸入資料流
- 字元緩衝輸出資料流
(1)BufferedReader:字元緩衝輸入資料流
構造方法
- public BufferedReader(Reader in)建立一個使用預設大小輸入緩衝區的緩衝字元輸入資料流。
- public BufferedReader(Reader in, int sz)建立一個使用指定大小輸入緩衝區的緩衝字元輸入資料流。
(2)BufferedWrier:文本寫入字元輸出資料流,緩衝各個字元,從而提供單個字元、數組和字串的高效寫入
構造方法
- BufferedWriter(Writer out) :預設緩衝區大小構造字元緩衝輸出資料流對象
- BufferedWriter(Writer out,int size):指定緩衝區大小
(3)字元緩衝輸出資料流:
- 特有功能:public void newLine():寫入一個行的分隔字元號
*字元緩衝輸入資料流:
- 特有功能:public String readLine():一次讀取一行
(4)使用字元緩衝流進行複製操作
分別使用兩種方式
- 1)一次讀取一個字元數組
- 2)一次讀取一行
(四)其他流
(1)記憶體操作流:適用於臨時隱藏檔.
記憶體操作輸入資料流:byteArrayInputStream
- ByteArrayInputStream(byte[] buf)
記憶體操作輸出資料流: byteArrayOutputStream
構造方法:ByteArrayOutputStream()
記憶體操作流:一個程式結束後,那麼這些程式的變數,就會從記憶體消失(馬上消失的這些資料進行讀取寫入)
(2)資料流:針對Java基本類型的資料進行讀寫操作
資料輸入流:DataInputStream
資料輸出資料流:DataOutputStream
(3)列印流
字元列印流(針對文本進行操作:PrintWriter)
位元組列印流(printStream 和標準輸出資料流有關係 System.out;)
PrintWriter:屬於輸出資料流
1)只能寫資料(只能針對目的地檔案進行操作),不能讀資料(不能針對源檔案進行操作)
2)可以針對檔案直接進行操作
如果一個類中的構造方法裡面有File對象或者String類型資料,這個類可以對文字檔直接操作
- FileInputStream
- FileOutputStream
- FileWriter
- FileReader..
- PrintWriter
- 3)自動重新整理功能::PrintWriter(OutputStream out/Writer out,boolean autoflush);第二個參數如果是true 表示啟動自動重新整理功能
- 4)列印的方法:print(XXX x)/println(XXX xx)
(4)合并流
SequenceInputStream 表示其他輸入資料流的邏輯串聯(合并流)
構造方法
- public SequenceInputStream(InputStream s1, InputStream s2)
- sequenceInputStream另一種構造方式
- public SequenceInputStream(Enumeration e)
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.SequenceInputStream;
import java.util.Enumeration;
import java.util.Vector;
/*
sequenceInputStream另一種構造方式
public SequenceInputStream(Enumeration e)
- 將多個輸入資料流對象進行合并
- a.txt+b.txt+c.txt--->d.txt
*/
public class SequenceInputStreamDemo2 {
public static void main(String[] args) throws IOException {
//StringDemo.java+SystemInDemo.java+PrintWriterDemo.java--->Copy.java檔案中
//定義一個集合VectorVector<InputStream> v = new Vector<InputStream>() ;//使用InputStream封裝檔案InputStream s1 = new FileInputStream("StringDemo.java") ;InputStream s2 = new FileInputStream("SystemInDemo.java") ;InputStream s3 = new FileInputStream("PrintWriterDemo.java") ;//將流對象添加到集合中v.add(s1) ;v.add(s2) ;v.add(s3) ;//特有功能Enumeration<InputStream> en = v.elements() ;//建立合并輸入資料流對象SequenceInputStream sis = new SequenceInputStream(en) ;//建立位元組緩衝輸出資料流對象BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("Copy.java")) ;//一次讀取一個位元組數組byte[] bys = new byte[1024] ;int len = 0 ;while((len=sis.read(bys))!=-1) { bos.write(bys, 0, len); bos.flush();}//關閉資源bos.close();sis.close();
}
}
(5)標準的輸入輸出資料流
- InputStream in = System.in
- PrintStream out = Syste.out ;
*jdk5以後,Java--->Scanner(InputStream in)
- 鍵盤錄入
- 1)Scanner
- 2)BufferedReader裡麵包裝字元轉換輸入流,封裝System.in
標準輸出資料流
PrintStream ps = System.out ;
使用BufferedWriter 去封裝System.out
(6)物件流程
序列化:將對象按照流的方式儲存到文字檔中或者再網路中傳輸 對象---->流資料 序列化流 (ObjectOutputStream)
還原序列化:將文字檔中的流對象或者網路傳輸中的流對象還原成對象 流資料--->對象 還原序列化流(ObjectInputStream)
java.io.NotSerializableException :當前類未實現序列化功能的異常
- Serializable:介面 沒有構造方法,沒有欄位,也沒有方法
介面---->標記介面
自訂類要實現序列化功能,必須實現介面Serializable介面
- 類實現了serializable也意味著他是標記類
- 假設之前操作針對Peroson操作序列的時候,產生一個標記 Preson.class--->固定ID 100
- name -100
- age -100
- 已經序列化完畢了,然後有修改了Person類裡面的一些東西,加入了toString()
- Person.class---固定id -- 200
(五)屬性集合類
(1)Properties:表示了一個持久的屬性集(簡稱:屬性集合類) extends Hashtable<K,V> Map集合的
- 可儲存在流中或從流中載入。屬性列表中每個鍵及其對應值都是一個字串。
- public Properties():無參構造
(2)屬性集合類的特有功能:
- public Object setProperty(String key, String value) :給屬性列表中添加鍵和值,並且強制都使用String
- public Set<String> stringPropertyNames():遍曆的功能
- public String getProperty(String key)用指定的鍵在此屬性列表中搜尋屬性
可儲存在流中或從流中載入,只能使用屬性集合類
public void store(Writer writer,String comments):把集合中的資料儲存文字檔中(屬性集合)
public void load(Reader reader):將文字檔中的資料載入到屬性集合中
(六)多線程
(1)何實現多線程程式呢?
要實現多線程程式,需要開啟進程,
開啟進程,是需要建立系統資源,但是Java語言不能建立系統資源
只有C/C++可以建立系統資源, 利用c語言建立好的系統資源實現
Java提供了一個類:Thread類
- 實現多線程程式的步驟:
- 1)將類聲明為 Thread 的子類
- 2)該子類應重寫 Thread 類的 run 方法
- 3)在主線程進行該自訂的線程類的對象的建立
並行和並發(高並發:MyBatis --->IBatis:半自動化)
強者邏輯上的同時,指的是同一個時間段內
後者物理上的同時,指的是同一個時間點
MyThread類就是一個執行線程類
並且重寫Thread類中的run 方法
run()方法裡面應該是一些耗時的操作,IO操作/迴圈語句..
(2)Thread 類提供了一些方法
- public final void setName(String name):給線程起名稱
- public final String getName() :擷取線程名稱
(3)跟線程優先順序相關的方法:
- public final int getPriority()返回線程的優先順序。
- public final void setPriority(int newPriority)更改線程的優先順序
- 線程存在一個預設優先順序
- public static final int MAX_PRIORITY 10 最大優先順序
public static final int MIN_PRIORITY 1 最小優先順序
public static final int NORM_PRIORITY 5 預設優先順序
(4)public final void setDaemon(boolean on) :true時,表示為守護線程
- 將該線程標記為守護線程或使用者線程。當正在啟動並執行線程都是守護線程時,JAVA 虛擬機器退出。(守護線程不會立即結束掉,它會執行一段時間在結束掉)
- 該方法必須在啟動線程前調用。
(5)方法
- public final void join():等待該線程終止 interruputedException 中斷異常
- public static void sleep(long millis):線程睡眠 指定是時間毫秒值
- throws InterruptedException
- 兩個區別?
public final void stop() ;強迫線程停止執行。 不會執行了 (過時了),方法能使用的
public void interrupt()中斷線程。 表示中斷線程的一種狀態
面試題
區別?
wait(): wait()調用的,立即釋放鎖 (同步鎖/Lock鎖)
sleep(): 線程睡眠,調用不會釋放鎖
- public final void stop() ;強迫線程停止執行。 不會執行了 (過時了),方法能使用的
- public static void yield()暫停當前正在執行的線程對象,並執行其他線程
Java基礎(九)