『壹』 JAVA中的Scanner類與IO流那些有什麼區別
publicclassTest{
publicstaticvoidmain(String[]args){
Scannersc=newScanner(System.in);
inti=sc.nextInt();
System.out.println(i);
}
}
從上面可以看到,Scanner類似一個容器,將輸入流放進去,然後通過nextXXX(),就可以通過特定的輸入流中獲取到數據,這個輸入流不僅可以是控制台輸入System.in,也可以是文件流如下:
Scannersc=newScanner(newFile("myNumbers"));
while(sc.hasNextLong()){
longaLong=sc.nextLong();
}
『貳』 java的io流包裝數據為什麼用byte類型數組。
因為計算機處理數據的單位就是位元組。所以,當我們處理磁碟文件和內存數據的時候,就正好選擇和計算機處理數據單位等大的數據類型來存儲數據。而且,我們調用的類庫中的API也都是使用這樣類型的參數。所以,我們就必須在編寫程序的時候使用byte類型的數組。
『叄』 java io流的典型使用方式有幾種
Java中IO流分成兩大類,
一種是輸入流,所有的輸入流都直接或間接繼承自InputStream抽象類,輸入流作為數據的來源,我們可以通過輸入流的read方法讀取位元組數據;
另一種是輸出流,所有的輸出流都直接或間接繼承自OutputStream抽象類,輸出流接收數據,可以通過write方法寫入位元組數據。
Java的IO流類中,大部分的輸入流和輸出流都是成對存在的,即如果存在XXXInputStream,那麼就存在XXXOutputStream,反之亦然。SequenceInputStream和StringBufferInputStream是特例,沒有對應的SequenceOutputStream類和StringBufferOutputStream類,許多IO操作都可能會拋出IOException異常,比如read、write、close操作。
以下是Java的IO流中常見的輸入流,由於每個輸入流都有其對應的輸出流,所以此處就不再列出輸出流的繼承結構圖。
1、ByteArrayInputStream & ByteArrayOutputStream:
ByteArrayInputStream構造函數中需要傳入一個byte數組作為數據源,當執行read操作時,就會從該數組中讀取數據,正如其名,是一種基於位元組數組實現的一種簡單輸入流,顯而易見的是,如果在構造函數中傳入了null作為位元組數據,那麼在執行read操作時就會出現NullPointerException異常,但是在構造函數初始化階段不會拋出異常;與之相對應的是ByteArrayOutputStream,其內部也有一個位元組數組用於存儲write操作時寫入的數據,在構造函數中可以傳入一個size指定其內部的byte數組的大小,如果不指定,那麼默認它會將byte數組初始化為32位元組,當持續通過write向ByteArrayOutputStream中寫入數據時,如果其內部的byte數組的剩餘空間不能夠存儲需要寫入的數據,那麼那麼它會通過調用內部的ensureCapacity
方法對其內部維護的byte數組進行擴容以存儲所有要寫入的數據,所以不必擔心其內部的byte數組太小導致的IndexOutOfBoundsException之類的異常。
2、FileInputStream & FileOutputStream
FileInputStream 能夠將文件作為數據源,讀取文件中的流,通過File對象或文件路徑等初始化,在其構造函數中,如果傳入的File對象(或與其相對應的文件路徑所表示的File對象)不存在或是一個目錄而不是文件或者由於其他原因無法打開讀取數據,都會導致在初始化階段導致拋出FileNotFoundException異常;與FileInputStream 相對應的是FileOutputStream,可以通過FileOutputStream向文件中寫入數據,也需要通過File對象或文件路徑對其初始化,如同FileInputStream ,如果傳入的File對象(或與其相對應的文件路徑所表示的File對象)是一個目錄而不是文件或者由於其他原因無法創建該文件寫入數據,都會導致在初始化階段拋出FileNotFoundException異常。
3、PipedInputStream & PipedOutputStream
PipedInputStream和PipedOutputStream一般是結合使用的,這兩個類用於在兩個線程間進行管道通信,一般在一個線程中執行PipedOutputStream 的write操作,而在另一個線程中執行PipedInputStream的read操作。可以在構造函數中傳入相關的流將PipedInputStream 和PipedOutputStream 綁定起來,也可以通過二者的connect方法將二者綁定起來,一旦二者進進行了綁定,那麼PipedInputStream的read方法就會自動讀取PipedOutputStream寫入的數據。PipedInputStream的read操作是阻塞式的,當執行PipedOutputStream的write操作時,PipedInputStream會在另一個線程中自動讀取PipedOutputStream寫入的內容,如果PipedOutputStream一直沒有執行write操作寫入數據,那麼PipedInputStream的read方法會一直阻塞PipedInputStream的read方法所運行的線程直至讀到數據。單獨使用PipedInputStream或單獨使用PipedOutputStream時沒有任何意義的,必須將二者通過connect方法(或在構造函數中傳入對應的流)進行連接綁定,如果單獨使用其中的某一個類,就會觸發IOException: Pipe Not Connected.
4、ObjectInputStream & ObjectOutputStream
ObjectOutputStream具有一系列writeXXX方法,在其構造函數中可以摻入一個OutputStream,可以方便的向指定的輸出流中寫入基本類型數據以及String,比如writeBoolean、writeChar、writeInt、writeLong、writeFloat、writeDouble、writeCharts、writeUTF等,除此之外,ObjectOutputStream還具有writeObject方法。writeObject方法中傳入的類型必須實現了Serializable介面,從而在執行writeObject操作時將對象進行序列化成流,並將其寫入指定的輸出流中。與ObjectOutputStream相對應的是ObjectInputStream,ObjectInputStream有與OutputStream中的writeXXX系列方法完全對應的readXXX系列方法,專門用於讀取OutputStream通過writeXXX寫入的數據。
5、SequenceInputStream
SequenceInputStream 主要是將兩個(或多個)InputStream在邏輯上合並為一個InputStream,比如在構造函數中傳入兩個InputStream,分別為in1和in2,那麼SequenceInputStream在讀取操作時會先讀取in1,如果in1讀取完畢,就會接著讀取in2。在我們理解了SequenceInputStream 的作用是將兩個輸入流合並為一個輸入流之後,我們就能理解為什麼不存在對應的SequenceOutputStream 類了,因為將一個輸出流拆分為多個輸出流是沒有意義的。
6、StringBufferInputStream
StringBufferInputStream允許通過在構造函數中傳入字元串以讀取位元組,在讀取時內部主要調用了String的charAt方法。與SequenceInputStream類似,StringBufferInputStream也沒有對應的OutputStream,即不存在StringBufferOutputStream類。Java沒有設計StringBufferOutputStream類的理由也很簡單,我們假設StringBufferOutputStream存在,那麼StringBufferOutputStream應該是內部通過執行write操作寫入數據更新其內部的String對象,比如有可能是通過StringBuilder來實現,但是這樣做毫無意義,因為一旦我們String的構造函數中可以直接傳入位元組數組構建字元串,簡單明了,所以設計StringBufferOutputStream就沒有太大的必要了。StringBufferInputStream這個類本身存在一點問題,它不能很好地將字元數組轉換為位元組數組,所以該類被Java標記為廢棄的(Deprecated),其官方推薦使用StringReader作為代替。
7、FilterInputStream & FilterOutputStream
FilterInputStream包含了其他的輸入流,說具體點就是在其構造函數中需要傳入一個InputStream並將其保存在其名為in的欄位中,FilterInputStream只是簡單的覆蓋了所有的方法,之所說是簡單覆蓋是因為在每個覆蓋函數中,它只是調用內部的保存在in欄位中的InputStream所對應的方法,比如在其覆蓋read方法時,內部只是簡單調用了in.read()方法。FilterInputStream的子類可以進一步覆蓋某些方法以保持介面不變的情況下實現某一特性(比如其子類有的可以通過使用緩存優化讀取的效率)或者提供一些其他額外的實用方法。所以在使用時FilterInputStream可以讓傳入的InputStream具有一些額外的特性,即對構造函數傳入的InputStream進行了一層包裹,使用了典型的裝飾著模式,如果只看FilterInputStream本身這一個類的話,則該類自己本身意義不大,因為其只是通過內部的欄位in簡單覆寫某些方法。但是如果將FilterInputStream 和其子類結合起來使用話,那麼就很有用了。比如FilterInputStream 有兩個子類BufferedInputStream和DataInputStream,這兩個類在下面還會詳細介紹。BufferedInputStream對read操作做了優化,每次讀操作時都讀取一大塊數據,然後將其放入內部維護的一個位元組數組緩沖區中。當外面調用BufferedInputStream的read方法時,首先去該緩沖區中讀取數據,這樣就避免了頻繁的實際的讀操作,BufferedInputStream對外沒有暴露額外的其他方法,但是其內部的read方法已經經過優化了,所以在執行讀操作的時候效率更高。DataInputStream與ObjectInputStream有點類似,可以通過一些readXXX方法讀取基本類型的數據,這是非常有用的一些方法。
8、BufferedInputStream & BufferedOutputStream
如上面所介紹的那樣,在BufferedInputStream的構造函數中需要傳入一個InputStream, BufferedInputStream內部有一個位元組數組緩沖區,每次執行read操作的時候就從這buf中讀取數據,從buf中讀取數據沒有多大的開銷。如果buf中已經沒有了要讀取的數據,那麼就去執行其內部綁定的InputStream的read方法,而且是一次性讀取很大一塊數據,以便填充滿buf緩沖區。緩沖區buf的默認大小是8192位元組,也就是8K,在構造函數中我們也可以自己傳入一個size指定緩沖區的大小。由於我們在執行BufferedInputStream的read操作的時候,很多時候都是從緩沖區中讀取的數據,這樣就大大減少了實際執行其指定的InputStream的read操作的次數,也就提高了讀取的效率。與BufferedInputStream 相對的是BufferedOutputStream。在BufferedOutputStream的構造函數中我們需要傳入一個OutputStream,這樣就將BufferedOutputStream與該OutputStream綁定在了一起。BufferedOutputStream內部有一個位元組緩沖區buf,在執行write操作時,將要寫入的數據先一起緩存在一起,將其存入位元組緩沖區buf中,buf是有限定大小的,默認的大小是8192位元組,即8KB,當然也可以在構造函數中傳入size指定buf的大小。該buf只要被指定了大小之後就不會自動擴容,所以其是有限定大小的,既然有限定大小,就會有被填充完的時刻,當buf被填充完畢的時候會調用BufferedOutputStream的flushBuffer方法,該方法會通過調用其綁定的OutputStream的write方法將buf中的數據進行實際的寫入操作並將buf的指向歸零(可以看做是將buf中的數據清空)。如果想讓緩存區buf中的數據理解真的被寫入OutputStream中,可以調用flush方法,flush方法內部會調用flushBuffer方法。由於buf的存在,會大大減少實際執行OutputStream的write操作的次數,優化了寫的效率。
『肆』 java判斷是不是基本類型,基本類型與對應的包裝類
byte short int long float double char boolean
區別很大,基本類型很特殊,內部用指針操作,包裝類就是一般的類
『伍』 java i/o各種封裝類 總結
常用的文件讀寫的類java.io.BufferedReader;
java.io.BufferedWriter;
java.io.File;
java.io.FileReader;
java.io.FileWriter;
一個簡單的實例:File file = new File("H:\\test.txt"); // 實例一個File對象,參數為文件路徑 // 判斷file對象是否是目錄 if (!file.isDirectory()) { FileReader fr = new FileReader(file); // 通過file對象實例一個文件讀取器
BufferedReader br = new BufferedReader(fr); // 該對象可以對文件進行讀取操作
FileWriter fw = new FileWriter("H:\\newtest.txt"); // 實例化一個文件寫入對象,參數為新文件名
BufferedWriter bw = new BufferedWriter(fw);
String strLine1 = br.readLine(); // 從文件中讀取一行1
String strLine2 = br.readLine(); // 從文件中讀取一行2
bw.write(strLine1); // 將strLine1寫入到新文件中
bw.newLine(); // 換行
bw.write(strLine2); // 再寫入一行 // 最後別忘了關閉這些讀寫對象,記得從下往上的順序關閉,即從最下層對象開始關
bw.close();
fw.close();
br.close();
fr.close(); // 調用這個可刪除文件
file.delete(); }
『陸』 java io流中裝飾器和過濾器的區別
樓主應該是領會了java io的精神的。在我以前學java的時候,與節點流相對的叫做包裝流。
分類的依據就是節點流是直接操作IO節點如ByteArray, File, Socket等等,所以相應的InputStream/OutputStream就是節點流。
包裝流是在java IO 管道機制中用來處理節點流的其他流對象,像各種Reader, Writer, Printer等等。他們的作用是在節點流基本功能至上提供擴展的功能,就像你說的對象、圖片、字元串等的對應特殊操作。
java IO中還有另一種分類就是:位元組流與字元流。位元組流顧名思義就是直接操作byte二進制數據;字元流則直接操作文本數據。例如:ByteArrayInputStream, ObjectOutputStream等是位元組流;BufferedReader, OutputStreamWriter等等是字元流。注意這個分類與上面節點流/包裝流的分類不是互斥的,只是兩種不同的分類體系。節點流通常都是位元組流;而一個流對象可以既是包裝流又是字元流,比如剛才說的OutputStreamWriter。
其實流的各種分類只不過是使我們更方便的理解IO包中類或對象的組織方式而已。不一定非要死摳字面。
B.T.W.
樓主所說的裝飾器應該與IO中使用頻繁的Decorator模式有關。而過濾器可能只是包裝流的不同說法。當然也不排除你的資料里它可能是有特指的,比如文件操作中的FileFilter等等。
回答也有點長,請耐心看完,好嗎?
『柒』 Java中有哪些常見的包裝流,包裝流的作用是什麼
包裝流:
1 有幾類,一類主要以過濾器流為主
如BufferedInputStream,BufferedOuputStream
DataInputStream,DataOutputStream
CheckedOutputStream
CipherOutputStream
DataOutputStream
DeflaterOutputStream
DigestOutputStream
PrintStream
。。。。
2 對象流、管道流、掃描器等其他流
3 包裝流,故名思義,目的是為了增強某種流的功能,如OutputStream,只負責輸出位元組,位元組數組,關閉等簡單的原始位元組操作。為了使其在輸出過程中具備更多的功能,如可以輸出數字,布爾值,整數,小數,對象,UTF字元串等,則可以使用DataOutputStream完成各種數據的輸出轉換,並且將轉換後的數據傳遞給被包裝得原始OutputStream流,如FileOutputStream
3 包裝流有個特點,必須有原始的具體的IO對象,不等獨立使用,如ObjectOutputStream,ObjectIputStream,都必須要有具體的輸出流對象FileOutputStream,SockeObjectOutputStream,因為包裝流本省不能真正完成輸入或者輸出過程,必須使用可以完成輸入、輸出流對象作為動作的真正執行者,包裝流不過簡化了調用者在輸入、輸出過程中的一些數據處理和特殊要求。
由於流系統比較復雜,可以從FileOutputStream流開始來學習
『捌』 java IO流,哪些是節點流,哪些是過濾流。
IO不是位元組流跟字元流嗎?
根據處理數據類型的不同分為:字元流和位元組流
根據數據流向不同分為:輸入流和輸出流
『玖』 java基本類型和包裝類的區別
int 是基本類型,直接存數值
Integer是類,產生對象時用一個引用指向這個對象
Java把內存劃分成兩種:一種是棧內存,另一種是堆內存
在函數中定義的一些基本類型的變數和對象的引用變數都是在函數的棧內存中分配
而實際的對象是在存儲堆內存中
即
int i = 5;//直接在棧中分配空間
Integer i = new Integr(5);//對象是在堆內存中,而i(引用變數)是在棧內存中
在堆中分配的內存,由java虛擬機的自動垃圾回收器來管理.
因為在堆中分配空間所需的時間遠大於從棧中分配存儲空間,所以JAVA速度比C 慢
當需要往ArrayList,HashMap中放東西時,像int,double這種基本類型是放不進去的,因為容器都是裝object的,這是就需要這些基本類型的外覆類了。Java中每種基本類型都有相應的外覆類。
int 和 Integer 的區別
java 提供兩種不同的類型:引用類型(或者封裝類型,Warpper)和原始類型(或內置類型,Primitive)。Int是java的原始數據類型,Integer是java為int提供的封裝類。Java為每個原始類型提供了封裝類。