一咖为、先看下必備知識:
1秕狰,流:系統(tǒng)內部和外部進行數據傳輸的管道。
2躁染,內部:內存鸣哀;外部:輸入設備,文件吞彤,網絡我衬。
3叹放,輸入(讀)通過輸入流對象,從外把數據傳送到內部挠羔。
4井仰,輸出(寫),從內到外破加,通過輸出流對象俱恶,把內存數據傳送到外部(網絡,文件范舀,顯示器控制臺)合是。
5,文本文件:
以ASCII碼方式存放的文件锭环,一般一個英文字符一個字節(jié)(以字節(jié)為單位)端仰,.txt某種意義上顯示器和鍵盤也叫文本文件。
如果想看見文件的內容田藐,這個文件必須以文本方式存放荔烧,所以顯示器也是文本文件,與內存存放方式(二進制)unicode碼不一樣汽久,將文件輸入內存鹤竭,使用需要轉換。
缺點:文本文件如果處理需要轉換景醇,效率低
6臀稚,二進制文件:
以內存方式存放,內部怎么用外部怎么存三痰,不可見吧寺,不能通過外部設備輸入
優(yōu)點:處理不需要轉換,效率高散劫,使用容易稚机。
//***
流:嚴格意義上只有一種,就是字節(jié)流获搏,jdk1.2版本增加了字符流赖条,其實也是字節(jié)流的變體。
字節(jié)流傳輸太慢常熙,又有過濾流(BufferedStream,DataStream,ObjectStream對象流)來套接纬乍,也叫套接流,假設字節(jié)流是個小管子裸卫,那么過濾流就是大管子仿贬,把大管子套接在小管子上,將字節(jié)流作為這些流的參數墓贿。另外茧泪,標準字節(jié)輸入輸出流(System.out/in/array)退个;還有管道流(PipedStream),經常用于線程之間调炬;順序輸入流(SequenceStream),將小管子接在一起成為長管子舱馅,等等缰泡,這些也全是字節(jié)流,內存流很少使用代嗤。
二棘钞、常用流
1、字節(jié)流
字節(jié)流是一個抽象類干毅,不是接口宜猜,因為輸入字節(jié)流的read()方法沒實現,輸出字節(jié)流的write()方法沒實現硝逢。不管是什么字節(jié)流姨拥,字節(jié)流的基類是inputStream OutputStream。
(1)inputStream 的一些常用方法:
對read做重載(三個)渠鸽,
int read();//從輸入流中讀一個字節(jié)叫乌,形成一個0~255之間的整數返回(是一個抽象方法)。
int read(byte b[]);//從流中讀取若干個字節(jié)的數據徽缚,存放到字節(jié)數組中憨奸,用于struts文件的上傳
int read(byte b[],int off,int len);//從輸入的字節(jié)流讀取lenth個字節(jié),從offset開始,放到字節(jié)數組中
close();//關閉
(2)OutputStream的一些常用方法:
對write做重載(三個)凿试,
write(int b);//將一個整數最低字節(jié)數據輸出到流中,
write(byte b[])//把內存的字節(jié)數組里的數據依次輸出到流所指向的文件
write(byte b[],int off ,int length)//將數組b中從off指定的位置開始排宰,長度為len的數據輸出到流中;
flush();//刷空輸出流,并將緩沖區(qū)中的數據強制送;一定要刷空那婉。
close();//關閉
2板甘、文件字節(jié)流
(1)文件字節(jié)流創(chuàng)建出輸入流和輸出流對象,
(2)文件輸入和輸出只作文本文件详炬,以順序操作虾啦,并且區(qū)分輸入流和輸出流。
例
import java.io.*;
class Filestream
{
public static void main(String args[])
{
try
{
File inFile=new File("file1.txt");
File outFile=new File("file2.txt");
//創(chuàng)建出輸入流和輸出流對象痕寓,
FileInputStream fis=new FileInputStream(inFile);
FileOutputStream fos=new ?FileOutputStream(outFile);
int c;
while((c=fis.read())!=-1) ?fos.write(c);
fis.close();//關閉
fos.close();
}catch(FileNotFoundException e) {
System.out.println("FileStreamsTest: "+e);
}catch(IOException e) {
System.err.println("FileStreamsTest: "+e);
}
}
}
3傲醉、隨機流
(1)類RandomAccessFile允許對文件內容同時完成讀和寫操作,它直接繼承object呻率,并且同時實現了接口DataInput和DataOutput硬毕,提供了支持隨機文件操作的方法:
(2)不區(qū)分輸入流輸出流,對文件訪問一定要指定訪問方式礼仗,(rw)可以隨機訪問文件某一位置的字符,可以以二進制的方式對數據進行存儲,可以隨機調整文件位置指針吐咳,隨機輸出逻悠。
(3)經典面試例子
例
import java.io.*;
public class random_file
{
public static void main(String args[])
{
int[] data_arr = {12,31,56,23,27,1,43,65,4,99};
try
{
RandomAccessFile randf = new RandomAccessFile("temp.dat","rw");
for (int i = 0; i < data_arr.length; i++)
randf.writeInt(data_arr[i]);
for(int i=data_arr.length-1; i>=0; i--)
{
randf.seek(i*4);
System.out.println(randf.readInt());//倒敘輸出
}
randf.seek(8);//跳8個字節(jié)輸出結果
System.out.println(randf.readInt());//56
System.out.println(randf.readInt());//23
randf.skipBytes(8);
System.out.println(randf.readInt());//43
randf.close();
}catch (IOException e){
System.out.println("File access error: "+e);
}
}
}
4、過濾流
(1)BufferStream
BufferInputStream和BufferOutputStream必須套接在字節(jié)流上韭脊,順序讀韧恕;
Buffer流是過濾流沪羔,不能單獨使用饥伊,并且區(qū)分輸入流和輸出流;
只能處理文本文件蔫饰,不能一次讀一行琅豆,一次能讀取若干字節(jié)的字符,沒有做本質的改變篓吁;
例
import java.io.*;
public class BufferedStreamDemo{
public static void main(String[] args){
try{
FileInputStream in = new FileInputStream(".//data1.txt");
BufferedInputStream fin = new BufferedInputStream(in);
FileOutputStream out = new FileOutputStream(".//data2.txt");
BufferedOutputStream fout = new BufferedOutputStream(out);
byte[] buf = new byte[512];
int c = 0;
while((c = fin.read(buf, 0, 512)) != -1){
System.out.println("c = " + c);
fout.write(buf, 0, c);
}
fin.close();
fout.close();
}catch(FileNotFoundException e){
System.out.println("File Not Found!");
}catch(IOException e){
System.out.println("I/O Error!");
}
}
}
(2)DataStream
Data流也是套接流茫因,一定要套接在字節(jié)流上,區(qū)分輸入輸出
DataInputStream
DataOutputStream
既可以套接文件字節(jié)流杖剪,也可以套接在網絡上(很多)
(1)套接在文件流上
(2)可以一次讀取一行的字符
(3)可以對漢字做編碼
(4)不僅處理文本文件冻押,也可以處理二進制文件
例
import java.io.*;
public class datainput_output
{
public static void main(String args[])throws IOException
{
FileOutputStream fos = new FileOutputStream("a.txt");
DataOutputStream dos = new DataOutputStream (fos);
try
{
dos.writeBoolean(true);
dos.writeByte((byte)123);
dos.writeChar('J');
dos.writeDouble(3.141592654);
dos.writeFloat(2.7182f);
dos.writeInt(1234567890);
dos.writeLong(998877665544332211L);
dos.writeShort((short)11223);
}
finally
{
dos.close();
}
FileInputStream ?fis = new FileInputStream("a.txt");
DataInputStream dis = new DataInputStream(fis);
try
{
System.out.println("\t "+dis.readBoolean());
System.out.println("\t "+dis.readByte());
System.out.println("\t "+dis.readChar());
System.out.println("\t "+dis.readDouble());
System.out.println("\t "+dis.readFloat());
System.out.println("\t "+dis.readInt());
System.out.println("\t "+dis.readLong());
System.out.println("\t "+dis.readShort());
}
finally
{
dis.close();
}
}
}
(3)ObjectStream
也是過濾流,只處理二進制文件盛嘿,不能處理文本文件
序列化:(串行化):把自己的狀態(tài)(屬性值)放在對象輸出流中傳送就叫翼雀。。
1孩擂,這個類一定要加入串行化協(xié)議String類和封裝類就加入了串行化協(xié)議狼渊。
2,創(chuàng)建出類的對象类垦,new Student()狈邑,為類的實例全局變量賦值。
3蚤认,創(chuàng)建對象輸出流米苹,先創(chuàng)建字節(jié)流,再套接在對象流上砰琢。
4蘸嘶,對象輸出流對象的writeObject()方法,寫進流中陪汽。
例
public class Student implements Serializable//串行化協(xié)議
{
int id;
String name;
int age;
String department;
public Student(int id, String name, int age, String department)
{
this.id = id;
this.name = name;
this.age = age;
this.department = departmernt;
}
}
反序列化:
通過文件對象輸入流讀取對象的狀態(tài)训唱,再生出對象。
1挚冤,創(chuàng)建對象輸入流對象况增,先創(chuàng)建文件輸入流對象。
2训挡,從對象所指文件讀取對象的狀態(tài)澳骤,readObject()再生成對象object造型為student歧强。
3,串行化加反串行化叫做對象的持續(xù)性为肮。
對象的串行化只保存對象的屬性(狀態(tài))摊册。
瞬時的狀態(tài)也不可保存,用transient標注颊艳,這時對象屬性不能傳送茅特。
例
public class Objectser
{
public static void main(String args[])
{
Student stu = new Student(981036,“Li Ming”, 16,“CSD”);
try
{
FileOutputStream fo = new FileOutputStream(“data.ser”);
ObjectOutputStream so = new ObjectOutputStream(fo);
so.writeObject(stu);
so.close();
}
catch(Exception e)
{
System.out.println(e) ;
}
}
}
5、管道流PipedStream
分管道輸入流和輸出流 籽暇,在線程中傳數據,生產者消費者模式與這個相結合饭庞。
例
import java.io.*;
/**
*管道流和生產者消費者相結合
*@TestPipePC測試管道流和線程結合類
*@Wang Cy 2016/0803
*/
public class TestPipePC
{
public static void main(String[] args)
{
//創(chuàng)建管道輸出流
PipedInputStream pis = ?new PipedInputStream();
//創(chuàng)建管道輸出流
try{
PipedOutputStream pos = new PipedOutputStream(pis);
//生產者線程
Producer p = new Producer(pos);
//創(chuàng)建消費者線程
Consumer c = new Consumer(pis);
//激活線程
p.start();
c.start();
}catch(IOException e){
System.out.println(e);
}
//管道流是不是無法實現三個或以上的線程通信
}
}
//生產者線程
class Producer extends Thread
{
private PipedOutputStream pos;
public Producer(PipedOutputStream pos)
{
this.pos = pos;
}
public void run()
{
int i = 0;
try {
while(i<10)
{
this.sleep(1000);
pos.write(i);
System.out.println("生產者:"+i);
i++;
}
} catch (IOException e) {
e.printStackTrace();
} catch(InterruptedException e2){
e2.printStackTrace();
}
}
}
//消費者線程
class Consumer extends Thread
{
private PipedInputStream pis;
public Consumer(PipedInputStream pis)
{
this.pis = pis;
}
public void run()
{
try
{
while(true)
{
System.out.println("消費者:"+pis.read());
}
} catch (IOException e1) {
}
}
}
6戒悠、順序輸入流SequenceStream
只對文件字節(jié)輸入流做鏈接
import java.io.*;
public class SequenceStream
{
public static void main(String args[])
{
try
{
FileInputStream f1,f2;
String s;
f1 = new FileInputStream("file1.txt");
f2 = new FileInputStream("data1.txt");
SequenceInputStream fs = new SequenceInputStream(f1, f2);//對兩個輸入流做連接
DataInputStream ds = new DataInputStream(fs);
while( (s = ds.readLine()) != null )
System.out.println(s);
f1.close();
f2.close();
}catch(FileNotFoundException e) {
System.out.println("FileStreamsTest: "+e);
}catch(IOException e) {
System.err.println("FileStreamsTest: "+e);
}
}
}
7、PrintStream標準流
被system繼承舟山,加載主方法時绸狐,通過system創(chuàng)建3個對象,in,out,err
8累盗、字符流
字符流不能讀取二進制文件寒矿,只能處理文本文件。
import java.io.*;
public class FileTOUnicode
{
public static void main(String args[])
{
try
{
FileInputStream fis = new FileInputStream("file1.txt");
InputStreamReader dis = new InputStreamReader(fis);
// InputStreamReader dis = new InputStreamReader(System.in);
BufferedReader reader = new BufferedReader(dis);
String s;
while( (s = reader.readLine()) != null )
{
System.out.println("read: "+s);
}
dis.close();
}catch(IOException e)
{
System.out.println(e);
}
}
}
?"?????u?vB??