1.打印流:可以將各種數據類型的數據都原樣打印
字節打印流 PrintStream 構造函數可以接收的參數類型:file對象,字符串路徑,字節輸出流OutputStream
字符打印流 PrintWriter 構造函數可以接收的參數類型:file對象,字符串路徑,字節輸出流OutputStream,字節輸出流Writer
import java.io.*;
class PrintStreamDemo
{
public static void main(String[] args)throws IOException
{
BufferedReader bufr=new BufferedReader(new InputStreamReader(System.in));//源,鍵盤錄入
PrintWriter out=new PrintWriter(new FileWriter("a.txt"),true);//目的,控制檯輸出
//PrintWriter out=new PrintWriter(new FileWriter("a.txt"),true);//目的改爲文件,用流包裝就可以了
String line=null;
while((line=bufr.readLine())!=null)
{
if("over".equals(line))
break;
out.println(line.toUpperCase());//println只要輸出流out返回值爲真,則可以自動刷新緩衝區
//out.flush();
}
out.close();
bufr.close();
}
}
2.SequenceStream:序列流,可以將多個分流合併一起再輸出
import java.io.*;
import java.util.*;
class SequenceDemo
{
public static void main(String[] args)throws IOException
{
Vector<FileInputStream> v=new Vector<FileInputStream>();//創建文件輸入流集合
v.add(new FileInputStream("d:\\1.txt"));
v.add(new FileInputStream("d:\\2.txt"));
v.add(new FileInputStream("d:\\3.txt"));
Enumeration<FileInputStream> en=v.elements();
SequenceInputStream sis=new SequenceInputStream(en);//創建合併流
FileOutputStream fos=new FileOutputStream("d:\\4.txt");//源:存入文件中
byte[] buf=new byte[1024];
int len=0;
while((len=sis.read(buf))!=-1)
{
fos.write(buf,0,len);
}
fos.close();
sis.close();
}
}
有了合併,自然也有切割:split
import java.io.*;
import java.util.*;
class SplitDemo
{
public static void main(String[] args)throws IOException
{
splitFile();
merge();
}
public static void merge()throws IOException//合併文件
{
ArrayList<FileInputStream> al=new ArrayList<FileInputStream>();
for(int x=1;x<=11;x++)
{
al.add(new FileInputStream("c:\\splitfiles\\"+x+".part"));
}
final Iterator<FileInputStream> it=al.iterator();//匿名內部類訪問的成員變量必須用final修飾
Enumeration<FileInputStream> en=new Enumeration<FileInputStream>()
{
//用於枚舉
public boolean hasMoreElements()
{
return it.hasNext();
}
public FileInputStream nextElement()
{
return it.next();
}
};
SequenceInputStream sis=new SequenceInputStream(en);
FileOutputStream fos=new FileOutputStream("c:\\splitfiles\\0.mp3");
byte[] buf=new byte[1024];
int len=0;
while((len=sis.read(buf))!=-1)
{
fos.write(buf,0,len);
}
fos.close();
sis.close();
}
public static void splitFile()throws IOException //切割方法
{
FileInputStream fis=new FileInputStream("c:\\feng1.mp3");//創建文件輸入流,關聯文件
FileOutputStream fos=null;
byte[] buf=new byte[1024*1024];
int len=0;
int count=1;
while((len=fis.read(buf))!=-1)//開始循環切割
{
fos =new FileOutputStream("c:\\splitfiles\\"+(count++)+".part");
fos.write(buf,0,len);
fos.close();
}
fis.close();
}
}
3.操作對象:ObjectInputStream,ObjectOutputStream,操作對象的持久序列化,以便於持久存儲
下面先創建了一個Person類
import java.io.*;
class Person implements Serializable //通過實現 java.io.Serializable 接口以啓用其序列化功能,如果不實現此接口,將無法被序列化
{
public static final long serialVersionUID=42L;//給類定義一個固定標識,之後無論類中成員有何變化,都可以讀出來
private String name;
transient int age; //被transient 修飾後,就不能再被序列化了
static String country="cn"; //注意:靜態是不能被序列化的
Person(String name,int age,String country)
{
this.name=name;
this.age=age;
this.country=country;
}
public String toString()
{
return name+"-"+age+country;
}
}
然後實現該對象的序列化
import java.io.*;
class ObjectStreamDemo
{
public static void main(String[] args)throws Exception
{
//writeobj();
readObj();
}
public static void readObj() throws Exception //將寫入的序列化對象讀出來
{
ObjectInputStream ois=new ObjectInputStream(new FileInputStream("obj.object")); //讀取出對象的基本數
Person p=(Person)ois.readObject(); //將讀取的數據還原成對象,並打印出來
System.out.println(p);
ois.close(); //關閉流
}
public static void writeobj()throws IOException //將對象實例化,寫入文件中,便於永久保存
{
ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("obj.object")); //將對象的基本數據寫入流中,通過在流中使用文件可以實現對象的持久存儲
oos.writeObject(new Person("lisi",39,"as")); //將指定的對象寫入 ObjectOutputStream
oos.close(); //關閉流
}
}
4.管道流,管道輸入流PipedInputStream,管道輸出流PipedOutputStream,兩個流分別由不同線程操作,否則容易造成死鎖
import java.io.*;
class Read implements Runnable //創建讀取線程
{
private PipedInputStream in;
Read(PipedInputStream in)//構造函數接收一個管道流進來
{
this.in=in;
}
public void run()
{
try
{
Thread.sleep(5000); //在讀之前讓線程先等待5秒
byte[] buf=new byte[1024]; //創建一個數組,用於接收讀取的數據
int len=in.read(buf); //將讀取的數據存入字節數組中
String s=new String(buf,0,len); //將字節數組返回String類型
System.out.println(s);
in.close();
}
catch(Exception e)
{
throw new RuntimeException("管道流讀取失敗");
}
}
}
class Write implements Runnable //寫入線程
{
private PipedOutputStream out;
Write(PipedOutputStream out) //接收寫入流進來
{
this.out=out;
}
public void run()
{
try
{
out.write("piped lai la".getBytes()); //開始寫入數據
out.close();
}
catch(IOException e)
{
throw new RuntimeException("管道流寫入失敗");
}
}
}
class PipedStreamDemo
{
public static void main(String[] args) throws IOException
{
//分別創建一個管道寫入流和讀取流
PipedInputStream in=new PipedInputStream();
PipedOutputStream out=new PipedOutputStream();
in.connect(out); //將管道讀取流和管道寫入流連接
//創建讀寫線程,並分別將流傳入線程
Read r=new Read(in);
Write w=new Write(out);
//開始運行線程
new Thread(r).start();
new Thread(w).start();
}
}
5.RandomAccessFile 隨機訪問文件,屬於IO包中成員,自身具備讀寫的方法,但該類直接繼承Object。內部封裝了一個數組,通過指針對數組元素進行操作,同時可以使用seks改變指針位置讀寫原理是將讀寫流封裝進了內部.
操作文件的模式有讀寫wr,只讀r.如果模式爲只讀r,不會創建文件,會去讀取一個已存在的文件,如果該文件不存在,再回報異常;如果該模式爲rw,而且該對象的構造函數要操作的文件不存在,會自動創建,如果存在,則不會覆蓋。
import java.io.*;
class RandomAccessFileDemo
{
public static void main(String[] args)throws IOException
{
writeFile();
writeFile_2();
//System.out.println(Integer.toBinaryString(258));
//readFile();
}
public static void readFile() throws IOException //數據讀取
{
RandomAccessFile raf=new RandomAccessFile("ran.txt","r");
raf.seek(8*3); //調整指針,獲取想要的數據
//跳過指定的字節數
//raf.skipBytes(8);
byte[] buf=new byte[4];//創建數組,便於存取數據字節
raf.read(buf);
String name=new String(buf);//將讀的字節數組轉化爲String型
int age=raf.readInt();//讀取年齡
System.out.println("name="+name);
System.out.println("age="+age);
raf.close();
}
public static void writeFile()throws IOException //寫入文件
{
RandomAccessFile raf=new RandomAccessFile("ran.txt","rw");//注意寫的時候的模式,還要能閱讀,所以是rw
raf.write("李四".getBytes());
raf.writeInt(97);
raf.write("王五".getBytes());
raf.writeInt(99);
raf.close();
}
public static void writeFile_2()throws IOException
{
RandomAccessFile raf=new RandomAccessFile("ran.txt","rw");
raf.seek(8*0); //調整指針,添加到指定位置
raf.write("週期".getBytes());
raf.writeInt(105);//讀取32位字節的數據,避免數據損失
raf.close();
}
}
6.DateStream:可以用於操作基本數據類型的數據流對象
import java.io.*;
class DataStreamDemo
{
public static void main(String[] args)throws IOException
{
//writeData();
//readData();
//writeUTFDemo();
readUTFDemo();
}
public static void writeData()throws IOException
{
DataOutputStream dos=new DataOutputStream(new FileOutputStream("data.txt"));//創建寫入流
//傳入各種基本數據類型
dos.writeInt(234);
dos.writeBoolean(true);
dos.writeDouble(76.52);
dos.close();
}
public static void readUTFDemo()throws IOException//讀utf格式編碼的數據
{
DataInputStream dis=new DataInputStream(new FileInputStream("utfdata.txt"));//創建讀取流
String s=dis.readUTF(); //只能也按照UTF格式編碼讀取
System.out.println(s);
dis.close();
}
public static void writeUTFDemo()throws IOException //寫utf格式編碼的數據
{
DataOutputStream dos=new DataOutputStream(new FileOutputStream("utfdata.txt"));
dos.writeUTF("你好");
dos.close();
}
public static void readData() throws IOException//讀取基本數據類型的方法
{
DataInputStream dis=new DataInputStream(new FileInputStream("data.txt"));
int num=dis.readInt();
boolean b=dis.readBoolean();
double d=dis.readDouble();
System.out.println(num);
System.out.println(b);
System.out.println(d);
}
}
7.ByteArrayStream,可以操作字節數組的流對象。數組流在內存中存在
ByteArrayInputStream:在構造的時候,需要接受數據源,而且數據源是一個字節數組
ByteArrayOutputStream:在構造的時候不用定義目的,因爲其本身就封裝了一個可變長度的字節數組。
對於這兩個流對象都有自身的數組,都沒有使用系統資源,所以不用關閉流
import java.io.*;
class ByteArrayStream
{
public static void main(String[] args)
{
ByteArrayInputStream bis=new ByteArrayInputStream("abcdedg".getBytes()); //數據源
ByteArrayOutputStream bos=new ByteArrayOutputStream(); //目的
int by=0;
while((by=bis.read())!=-1) //讀取數據
{
bos.write(by); //寫入數據
}
System.out.println(bos.size());
System.out.println(bos.toString());
}
}