黑馬程序員java基礎之io流中的其他流

------- android培訓java培訓、期待與您交流! ----------

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());
	}
}





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章