java學習之IO流1

IO流用來處理設備之間的數據傳輸
           流按操作數據分爲兩種:字節流與字符流
           流按流向分爲:輸入流和輸出流
           
輸入流和輸出流相對於內存設備而言:
            將外設中的數據讀取到內存中:輸入
            將內存的數據寫入到外設中:輸出

字符流的由來:
其實就是字節流讀取文字字節數據後,不直接操作而是先查指定的編碼表,獲取對應的文字,
再對這個文字進行操作。簡單說:字節流+編碼表

字符流的兩個頂層父類:
             1.InputStream    2.OutputStream
字符流的兩個頂層父類:
             1.Reader    2.Writer

這些體系的子類都以父類名作爲後綴,而且子類名的前綴就是該對象的功能

如果要操作文字數據,優先考慮字符流,而且要將數據從內存寫到硬盤上,要使用字符流中的輸出流。(Writer)


字符流:

FileWriter:

示例1:

下圖中第3行創建一個可以往文件中寫入字符數據的字符輸出流對象,既然是往一個文件中寫入文件數據,那麼再創建對象時,就必須明確該文件(用於存儲數據的目的地),所以構造函數中指定的形參爲寫入的文件地址和文件名。沒有指定地址則默認爲當前目錄。如果指定的文件不存在,則會自動創建,如果文件存在,則會被覆蓋(覆蓋的意思是原文件中的數據會被清空,被一個新建立的文件替換)。第4行用write方法把字符串"abc"寫入文件當中,此時查看文件,會發現文件中並沒有寫入的字符串"abc",是因爲此時的字符串是先存儲在臨時緩衝區中,所以必須調用flush方法刷新緩衝區,把數據立即寫入預期目標。如果調用close方法,則會先刷新緩衝區,即調用flush()方法,然後再關閉流,在關閉該流之後,再調用 write() 或 flush() 將導致拋出 IOException

        public static void demo1() throws IOException 
	{
		FileWriter fw = new FileWriter("demo.txt");
		fw.write("abc");
//		fw.flush();
		fw.close();
	}

示例2:

如果在寫入數據的時候需要換行,在windows系統下的換行符號是“\r\t”。也可以如下圖第1行,聲明一個常量,用System類中的getProperty("line.separator")方法獲取當前系統的換行符,這樣就不需要在意當前的操作系統了。如果要在一個已有數據的文件中追加數據,需要在構造函數中加入true表示對文件進行續寫,如第7行,否則新寫入的數據會覆蓋原數據。

	private static final String LINE_SEPARATOR = System.getProperty("line.separator");
	public static void demo2() throws IOException
	{
		FileWriter fw = new FileWriter("demo2.txt");
		fw.write("abc" + LINE_SEPARATOR + "def");
		fw.close();
		FileWriter fw1 = new FileWriter("demo2.txt", true);
		fw1.write("haha");
		fw1.close();
	}

FileWriter IO異常處理

實例3:

下圖中第6、7、18行都可能出現異常,所以用try-catch處理異常。無論有沒有出現異常,都要執行第18行,所以把它放在了finally語句塊中,爲了能在finally中使用fw對象引用,就把fw定義在try語句塊之外,如第3行。如果第6行建立對象時出現了異常,那麼fw就不能參考至對象,就會出現空指針異常java.lang.NullPointerException,所以必須加入判斷fw是否爲空,如第15行所示。

	public static void demo3() 
	{
		FileWriter fw = null;
		try 
		{
			fw = new FileWriter("k:\\demo2.txt");
			fw.write("abcdef");
		} 
		catch (IOException e) 
		{
			System.out.println(e.toString());
		}
		finally
		{
			if(fw != null)
				try
				{
					fw.close();
				}
				catch(IOException e)
				{
					throw new RuntimeException("關閉失敗");
				}
		}
	}

FileReader:

示例1:

下圖中第3行創建讀取字符數據的流對象,在構造函數中明確了要讀取的文件,即用一個讀取流關聯一個已存在的文件。第4行用read()方法讀取一個字符,返回的是一個整數。第5行中打印出來的值爲97,字符a對應的ASCII碼,第6行把97轉換成char類型的,打印出來爲a。如果讀取已經達到流的末尾,就返回-1。

	public static void demo1() throws IOException 
	{
		FileReader fr = new FileReader("demo.txt");
		int ch = fr.read();
		System.out.println(ch);//97
		System.out.println((char)ch);//a
		fr.close();
	}

示例2:

下圖中使用的是read()方法讀取多個字符,存儲在一個字符數組中。第5行返回的是實際讀取到的個數,並把讀到的字符存儲在buf數組中。如果文件中字符的長度大於數組長度時,那麼一次最多隻能讀到的個數等於數組的長度。如果讀到流的末尾沒有數據了,會返回-1。所以可以用循環的方式來讀取,如第9-11行。第11行是把char類型的數組buf轉換成String類型,從0號下標開始,轉換的個數爲len。

	public static void demo2() throws IOException
	{
		FileReader fr = new FileReader("demo.txt");
		char[] buf = new char[5];
//		int num = fr.read(buf);
//		System.out.println("讀到的個數 = " + num);//讀到的個數 = 5
//		System.out.println(new String(buf));//abcde
		int len = 0;
		while((len = fr.read(buf)) != -1)
		{
			System.out.println(new String(buf, 0, len));
			/*輸出 abcde
			     f*/
		}
	}

爲了提高寫入的效率,可以使用字符流的緩衝區

如下圖中,第4行創建一個字符流的緩衝區對象,並和指定要被緩衝的流對象相關聯的。第5行使用緩衝區的寫入方法將數據先寫入到緩衝區中。第6行使用緩衝區的方法,寫入一個換行分隔符。第8行使用緩衝區的刷新方法將數據刷到目的地中。第9行關閉緩衝區,其實就是關閉流,即調用fw.close();

	public static void demo1() throws IOException 
	{
		FileWriter fw = new FileWriter("demo.txt");
		BufferedWriter bufw = new BufferedWriter(fw);
		bufw.write("abcdefg");
		bufw.newLine();
		bufw.write("hijk");
		bufw.flush();
		bufw.close();
	}

如下圖中,第4行創建了一個讀字符流的緩衝區對象,並和指定要被緩衝的流對象關聯。第5行使用緩衝區對象的readLine()方法每次讀取一行(行是以回車換行符來區分的),並返回字符串。當數據都讀完是,會返回null。

	public static void demo1() throws IOException 
	{
		FileReader fr = new FileReader("demo.txt");
		BufferedReader bufr = new BufferedReader(fr);
		String line1 = bufr.readLine();
		System.out.println(line1);//abcdefg
		String line2 = bufr.readLine();
		System.out.println(line2);//hijk
		String line3 = bufr.readLine();
		System.out.println(line3);//null
		fr.close();
	}


字符流:

FileOutputStream:

下圖中第6行把字符串“abcdefg”轉換成byte數組,因爲字符流只能操作字節數組。使用write方法寫數據後,不需要使用臨時緩衝,會直接將數據寫到目的地中,這是字節流的一個特點。

	public static void demo_write() throws IOException
	{
		//創建字節輸出流對象,用於操作文件
		FileOutputStream fos = new FileOutputStream("bytedemo.txt");
		//寫數據,直接寫入到了目的地中
		fos.write("abcdefg".getBytes());
		fos.close();//關閉資源
		
	}

下圖中第3行創建了字節輸入流對象,構造函數中關聯了要操作的文件。第四行創建了一個字節數組,長度爲fis.available(),該方法是獲得當前操作文件的大小,對於小文件可以這樣使用,對於大文件不能這樣使用,不然會導致內存空間不足。第7行把字節數組轉換成爲字符串輸出。

	public static void demo_read() throws IOException 
	{
		FileInputStream fis = new FileInputStream("demo.txt");
		byte[] buf = new byte[fis.available()];
		System.out.println(fis.available());
		fis.read(buf);
		System.out.println(new String(buf));
		fis.close();
	}

字節流複製MP3文件的四種方法:

方法一:

使用字節輸出流和字節輸入流,建立一個長度爲1024的字節數組來存放數據。使用while循環進行讀寫。

	public static void copy_1() throws IOException
	{
		FileInputStream fis = new FileInputStream("D:\\酷狗音樂\\KuGou\\在他鄉.mp3");
		FileOutputStream fos = new FileOutputStream("D:\\1.mp3");
		byte[] buf = new byte[1024];
		int len = 0;
		while((len = fis.read(buf)) != -1)
		{
			fos.write(buf, 0, len);
		}
		fos.close();
		fis.close();
	}
方法二:

使用緩衝區來進行數據的讀寫,加快了速度。

	public static void copy_2() throws IOException
	{
		FileInputStream fis = new FileInputStream("D:\\酷狗音樂\\KuGou\\在他鄉.mp3");
		BufferedInputStream bufis = new BufferedInputStream(fis);
		FileOutputStream fos = new FileOutputStream("D:\\2.mp3");
		BufferedOutputStream bufos = new BufferedOutputStream(fos);
		int ch = 0;
		while((ch = bufis.read()) != -1)
		{
			bufos.write(ch);
		}
		bufos.close();
		bufis.close();
	}
方法三:

直接使用available()方法獲取文件的大小,建立一個長度剛剛好的字節數組,進行一次性讀,一次性寫。

	public static void copy_3() throws IOException 
	{
		FileInputStream fis = new FileInputStream("D:\\酷狗音樂\\KuGou\\在他鄉.mp3");
		FileOutputStream fos = new FileOutputStream("D:\\3.mp3");
		byte[] buf = new byte[fis.available()];
		fis.read(buf);
		fos.write(buf);
		fos.close();
		fis.close();
	}
方法四:

使用字節輸入流,字節輸出流,讀取一個字節,寫入一個字節,這樣的操作很慢,效率低。

	public static void copy_4() throws IOException
	{
		FileInputStream fis = new FileInputStream("D:\\酷狗音樂\\KuGou\\在他鄉.mp3");
		FileOutputStream fos = new FileOutputStream("D:\\4.mp3");
		int ch = 0;
		while((ch = fis.read()) != -1)
		{
			fos.write(ch);
		}
		fos.close();
		fis.close();
	}












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