java基礎---------IO輸入輸出之字節流



IO流分類:

(1):按照流向可以分爲:
輸入流:讀取數據;
輸出流:寫出數據;
(2):按照數據類型:
字節流
字節輸入流:讀取數據 InputStream 需要有文件。
字節輸出流:寫出數據 OutputStream 不需要自己再創建文件
字符流 
字符輸入流:讀取數據 Reader
字符輸出流:寫出數據 Writer
字符流是在字節流之後纔出現的。

字節流輸出:
構造方法:
FileOutputStream(File file)
FileOutputStream(String name)

通過查API可知public abstract class OutputStream extends Object implements Closeable, Flushable{}OutputStream實爲抽象類。因此需要創建對象時,要麼使用多態,要麼通過其子類創建對象。


OutputStream寫出常用操作:
public void write(int a);
public void write(byte [] b);
public void write(byte[] b,int off,int len);


寫出數據案例:
第一種方法:
import java.io.FileOutputStream;
import java.io.IOException;
public class WriterDemo{
	public static void main(String [] args)throws IOException{
		FileOutputStream fos=new FileOutputStream("e:\\it.txt");
		//將字符串轉爲字節數組。
		fos.write("我愛黑馬".getBytes());
		fos.close();
	}
}



第二種方法:
import java.io.FileOutputStream;
import java.io.IOException;
public class WriterDemo{
	public static void main(String [] args)throws IOException{
		FileOutputStream fos=new FileOutputStream("e:\\it.txt");
		fos.write(97);//寫入a;
		fos.close();
	}
}




第三種方法:
import java.io.FileOutputStream;
import java.io.IOException;
public class WriterDemo{
	public static void main(String [] args)throws IOException{
		FileOutputStream fos=new FileOutputStream("e:\\it.txt");
		byte [] by={97,98,99,100,101};
		fos.write(by,1,2);//輸出bc
		fos.close();
	}
}


 
創建字節輸出流,對象做了三件事:
1、調用系統功能創建文件。
2、創建fos對象。
3、將fos對象指向這個文件。


爲什麼一定要加close?
1、讓流對象關閉。讓流對象變成垃圾,這樣就可以被垃圾回收器回收了。
2、通知系統釋放與該文件相關的資源。


換行符:
windows:\r\n
linux:\n
Mac:\r


追加寫入:用構造方法帶第二個參數是true的情況即可。

字節流中處理異常:

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;


public class Copy{
	public static void main(String[] args) {		
		FileOutputStream fos= null;
		try{
			fos=new FileOutputStream("e:\\it.txt");
			fos.write("java".getBytes());			
		}catch(FileNotFoundException e){
			e.printStackTrace();			
		}catch(IOException e){
			e.printStackTrace();
		}finally{
			if(fos!=null){
				try {	
					fos.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
}





讀取數據:InputStream:抽象類。


常用操作
int read();一次讀取一個字節;返回的是int值,需要我們用char轉爲字符。
int read(byte [] b);一次讀取一個字節數組


一次讀取一個字節讀取數據:
import java.io.FileInputStream;
import java.io.IOException;
public class ReaderDemo{
	public static void main(String [] args)throws IOException{
		FileInputStream fis=new FileOutputStream("e:\\it.txt");
		int by=0;
		//讀取完成,返回的是-1;
		while((by=fis.read())!=-1){
			//char強制轉換,將讀取的值轉變爲字符。如果此時我們輸出的是fos.read()的話,它就會像迭代器中的it.next()一樣,會出現跳躍輸出。因爲fos.read()已經在while循環的條件控制中已經出現了,如果在輸出中繼續出現,實際就是輸出下一個了。
			System.out.print((char)by);
		}
		fis.close();
	}
}


注意:上面的例子我們可以看到,當一個字節,一個字節讀取的時候,中文字符會被解析爲亂碼。這是因爲中文字符實爲兩個字節,不能拆開。之所以是-1;是因爲JDK中,當文件讀完時,會返回-1.由於讀取的是字節,在控制檯顯示的是二進制轉化爲十進制後的數字,因此要用char強制轉換成字符。


計算機如何讀取中文。
這是由於中文的一個字符,分爲兩個字節,每個字節都是負數。這兩個負數都是在0到-128之間,因此可以使用byte數組。128*128等於16384,所以漢字常用字符夠用。


一次讀取一個字節來複制文件:
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class CopyDemo{
	public static void main(String [] args)throws IOException{
			//複製到e盤的it.txt文件
		FileOutputStream fos=new FileOutputStream("e:\\it.txt");
			//創建對象,讀取D盤中的it.txt文件。
		FileInputStream fis=new FileInputStream("d:\\it.txt");
		int by=0;
		while((by=fis.read())!=-1){
			fos.write(by);
		}
		fos.close();
		fis.close();
	}
}

注意:通過字節讀取寫出,不僅可以賦值txt文檔,還可以賦值jpg,map4等多種文件。只需要將文件名換一下就可以了。


一次讀取一個字節數組:
import java.io.FileInputStream;
import java.io.IOException;
public class ReadDemo{
	public static void main(String [] args)throws IOException{
		FileInputStream fos=new FileInputStream("e:\\it.txt");		
		byte [] by=new byte[1024];
		int len=0;
	//fis.read(by)將會返回實際讀取到的字節個數。
		while((len=fis.read(by))!=-1){
			System.out.print(new String(by,0,len));
		}
		fis.close();
	}
}


注意:通過一次讀取一個字節數組的長度來讀取文件,這裏的字節數組的長度需要自己規定。每次讀取文件的時候,都會讀取規定長度個字節,其中包括\r、\n這樣的轉義字符。因此當規定長度小於文件字節長度時,最後一次讀取到的字節,就無法覆蓋完上一次讀取的長度的個元素,因此就會多出一些上一次讀取最後多餘的元素。


一次讀取一個字節數組來複制文件:
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class CopyDemo{
	public static void main(String [] args)throws IOException{
<span style="white-space:pre">		</span>//複製到e盤的it.txt文件
<span style="white-space:pre">		</span>FileOutputStream fos=new FileOutputStream("e:\\it.txt");
<span style="white-space:pre">		</span>//創建對象,讀取D盤中的it.txt文件。
<span style="white-space:pre">		</span>FileInputStream fis=new FileInputStream("d:\\it.txt");
<span style="white-space:pre">		</span>byte [] by=new byte[1024];
<span style="white-space:pre">		</span>int len =0;
<span style="white-space:pre">		</span>while((len=fis.read(by))!=-1){
<span style="white-space:pre">			</span>fos.write(by,0,len);
<span style="white-space:pre">		</span>}
<span style="white-space:pre">		</span>fos.close();
<span style="white-space:pre">		</span>fis.close();
<span style="white-space:pre">	</span>}
}




緩衝區類:
寫數據:BufferedOutputStream
讀數據:BufferedInputStream


字節緩衝區流,僅僅提供緩衝區,其是爲高效而設計的。真正的讀寫操作還得靠基本的流對象實現。


構造方法可以指定緩衝區大小,但是默認緩衝區就夠用了。
寫出案例:
import java.io.IOException;
import java.io.FileOutputStream;
class BufferedOutputStreamDemo{
	public static void main(String [] args)throws IOException{
		FileOutputStream fos=new FileOutputStream("e:\\it.txt");
		BufferedOutputStream bos=new BufferedOutputStream(fos);
		bos.write("hello".getBytes());
		bos.close();
	}
}




讀取案例:

import java.io.IOException;
import java.io.FileInputStream;
class BufferedInputStreamDemo{
	public static void main(String [] args)throws IOException{
		FileInputStream fis=new FileInputStream("e:\\it.txt");
		BufferedInputStream bis=new BufferedInputStream(fis);
		int by=0;
		while((by=bis.read()!=-1){
			System.out.print((char)by);
		}
		bis.close();
	}
}




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