黑馬程序員_JAVA_IO(一)

------Java培訓、Android培訓、iOS培訓、.Net培訓、期待與您交流! -------

一、IO流概述

特點:

        1IO流用來處理設備間的數據傳輸。

        2Java對數據的操作是通過流的方式。

        3Java用於操作流的對象都在IO包中。

        4流按操作數據分爲兩種:字節流和字符流。

        5流按流向分爲:輸入流和輸出流。

常用基類:

        1字節流的抽象基流:InputStreamOutputStream

        2字符流的抽象基流:ReaderWriter

字符流與字節流:

1、字符流中的對象融合了編碼表。使用的是默認的編碼,即當前系統的編碼。

        2、字符流只用於處理文字數據,而字節流可以處理媒體數據。

注意:此四個類派生出來的子類名稱都是以父類名作爲子類名的後綴,以前綴爲其功能;如:FileInputStream,FileOutputStream和FileReader,FileWriter;流只能操作數據,而不能操作文件。


二、字符流操作

FileWriter類:

        1、創建一個FileWriter對象,該對象一被初始化,就必須要明確被操作的文件。且該目錄下如果已有同名文件,則同名文件將被覆蓋。其實該步就是在明確數據要存放的目的地。

        2、調用write(String s)方法,將字符串寫入到流中。

        3、調用flush()方法,刷新該流的緩衝,將數據刷新到目的地中。

        4、調用close()方法,關閉流資源。但是關閉前會刷新一次內部的緩衝數據,並將數據刷新到目的地中。

注意:

        1、其實java自身不能寫入數據,而是調用系統內部方式完成數據的書寫,使用系統資源後,一定要關閉資源。

        2、文件的數據的續寫是通過構造函數 FileWriter(Strings,boolean append),在創建對象時,傳遞一個true參數,代表不覆蓋已有的文件。並在已有文件的末尾處進行數據續寫。(windows系統中的文件內換行用\r\n兩個轉義字符表示,在linux系統中只用\n表示換行)

        3、由於在創建對象時,需要指定創建文件位置,如果指定的位置不存在,就會發生IOException異常。

import java.io.FileWriter;
import java.io.IOException;
class FileWriterDemo {
	public static void main(String[] args) throws IOException {
		FileWriter fw = new FileWriter("demo.txt");
		fw.write("abcde");
		// fw.flush();
		fw.close();
	}
}

FileReader類:

        1、創建一個文件讀取流對象,和指定名稱的文件相關聯。要保證該文件已經存在,若不存在,將會發生異常

        2調用讀取流對象的read()方法。

        3讀取後要調用close方法將流資源關閉。

import java.io.FileReader;
import java.io.IOException;
class FileReaderDemo {
	public static void main(String[] args) throws IOException {
		FileReader fr = new FileReader("demo.java");// 創建FileReader流對象
		char[] buf = new char[1024]; // 創建一個緩衝區
		int num = 0;

		while ((num = fr.read(buf)) != -1) { // 循環讀取文件,讀到文件末尾則返回-1
			System.out.print(new String(buf, 0, num)); // 打印讀取的內容
		}
		fr.close(); // 關閉資源
	}
}


三、字符流的緩衝區

1、緩衝區的出現:提高了流的讀寫效率,所以在緩衝區創建前,要先創建流對象。即先將流對象初始化到構造函數中。 

2、緩衝技術原理:此對象中封裝了數組,將數據存入,再一次性取出。

字符流的緩衝區類: BufferedWrite, BufferedReader

緩衝區要結合流纔可以使用,在流的基礎上對流的功能進行了增強。

BufferedWrite提供了一個跨平臺的換行方法,newLine();

BufferedReader提供了一個讀一行的方法,readLine()不包含行終止符。當返回null是,表示已經讀到了文件的末尾。

因爲在BufferedReader和BufferedWrite中調用了相應的流對象,所以只需要關閉BufferedReader和BufferedWrite,釋放資源。

//使用緩衝技術copy一個文本文件
import java.io.*;
class BufferedCopyDemo {
	public static void main(String[] args) {
		BufferedWriter bfw = null;
		BufferedReader bfr = null;
		try {
			// 創建寫緩衝對象
			bfw = new BufferedWriter(new FileWriter("a.txt"));
			// 創建讀緩衝對象
			bfr = new BufferedReader(new FileReader("b.java"));
			// 利用BufferedReader提供的readLine方法獲取整行的有效字符。
			for (String line = null; (line = bfr.readLine()) != null;) {
				bfw.write(line);
				bfw.newLine();
				bfw.flush();// 將緩衝區數據刷到指定文件中
			}

		} catch (IOException e) {
			throw new RuntimeException("文件copy失敗");
		} finally {
			if (bfw != null)
				try {
					bfw.close();// 關閉寫入流
				} catch (IOException e) {
					throw new RuntimeException("寫入流關閉失敗");
				}
			if (bfr != null)
				try {
					bfr.close();// 關閉讀取流
				} catch (IOException e) {
					throw new RuntimeException("讀取流關閉失敗");
				}
		}
	}
}


自定義BufferedReader
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
// 自定義BufferedReader類
class MyBufferedReader {
	private FileReader fr;

	public MyBufferedReader(FileReader fr) {
		this.fr = fr;
	}

	public String readLine() throws IOException {
		StringBuilder sb = new StringBuilder();
		int ch = 0;
		while ((ch = fr.read()) != -1) {
			char c = (char) ch;
			if (c == '\r')
				continue;
			if (c == '\n')
				return sb.toString();
			else
				sb.append((char) ch);
		}
		if (sb.length() != 0) {
			return sb.toString();
		}
		return null;
	}

	public void close() throws IOException {
		if (fr != null)
			fr.close();
	}
}


LineNumberReader類:

         void setLineNumber();//設置初始行號

         int getLineNumber();//獲取行號

import java.io.FileReader;
import java.io.IOException;
import java.io.LineNumberReader;
class LineNumberReaderDemo {
	public static void main(String[] args) {
		LineNumberReader lnr = null;
		try {
			// 將讀取流對象傳入
			lnr = new LineNumberReader(new FileReader("a.java"));
			lnr.setLineNumber(100);// 設置開始行號

			for (String line = null; (line = lnr.readLine()) != null;) {
				System.out.println(lnr.getLineNumber() + ":" + line);// 打印每行行號和字符
			}
		} catch (IOException e) {
			throw new RuntimeException("讀取數據失敗");
		} finally {
			try {
				if (lnr != null)
					lnr.close();
			} catch (IOException e) {
				throw new RuntimeException("讀取流關閉失敗");
			}
		}
	}
}


四、字節流操作

1、字節流和字符流的基本操作是相同的,但字節流還可以操作其他媒體文件。

2 因爲字節流操作的是字節,即數據的最小單位,不需要像字符流一樣要進行轉換爲字節。所以可直接將字節數據寫入到指定文件中。

3InputStream特有方法: int available();//返回文件中的字節個數

使用字節流複製圖片實例:

import java.io.*;
class CopyPic {
	public static void main(String[] args) {
		byteArrayCopy();
	}
	// 使用讀數組方式進行復制
	public static void byteArrayCopy() {
		FileInputStream fis = null;
		FileOutputStream fos = null;
		try {
			// 關聯要複製的文件
			fis = new FileInputStream("1.jpg");
			// 指定複製的路徑
			fos = new FileOutputStream("2.jpg");
			// 利用數組的讀取方式
			byte[] b = new byte[1024];
			int len = 0;
			while ((len = fis.read(b)) != -1)// 複製文件的全部數據
			{
				fos.write(b, 0, len);// 粘貼到指定路徑
			}
		} catch (IOException e) {
			throw new RuntimeException("圖片複製失敗");
		} finally {
			try {
				if (fis != null)
					fis.close();// 關閉輸入字節流
			} catch (IOException e) {
				throw new RuntimeException("讀取字節流關閉失敗");
			}
			try {
				if (fos != null)
					fos.close();// 關閉輸出字節流
			} catch (IOException e) {
				throw new RuntimeException("寫入字節流關閉失敗");
			}
		}
	}
}


五、字節流的緩衝區

BufferedInputStream、BufferedOutputStream

其原理與BufferedReader、BufferedWriter基本相同

自定義BufferedInputStream:

import java.io.IOException;
import java.io.InputStream;
public class MyBufferedInputStreamDemo {
	private InputStream in;
	private byte[] buf = new byte[1024];
	private int count = 0, pos = 0;

	public MyBufferedInputStreamDemo(InputStream in) {
		this.in = in;
	}
	/*
	 * 注意:爲什麼不返回byte類型而返回int類型
	 * 因爲byte類型出現11111111時的值爲-1,不利於判斷,
	 * 而轉換爲int類型時則又會出現32個1的情況.
	 * 所以結果的最後byte要和255相與
	 */
	public int myRead() throws IOException {
		if (count == 0) {
			count = in.read(buf);
			if(count < 0){
				return -1;
			}
			byte b = buf[pos];
			count--;
			pos++;
			return b & 255;
		} else if (count > 0) {
			byte b = buf[pos];
			count--;
			pos++;
			return b & 0xff;
		}else{
			return -1;
		}
	}
}


六、鍵盤錄入和轉換流的應用

1、標準輸入輸出流

        System.in:對應的標準輸入設備,鍵盤。類型是InputStream。

        Ssytem.out:對應的是標準的輸出設備,控制檯。PrintStream,FilterOutputStream的子類。


轉換流

轉換流的由來:

       a、字符流與字節流之間的橋樑

       b、方便了字符流與字節流之間的操作

轉換流的應用:

      字節流中的數據都是字符時,轉成字符流操作更高效。在使用轉換流時可以指定字符編碼

1、 InputStreamReader將字節流通向字符流

              BufferedReader  in = new BufferedReader(new InputStreamReader(System.in));

2、OutputStreamWriter字符流通向字節流

              BufferedWriteroutnew BufferedWriter(new OutputStreamWriter(System.out));

import java.io.*;
class TransStreamDemo {
	public static void main(String[] args) throws IOException {
		// 鍵盤錄入最常見寫法
		BufferedReader in = new BufferedReader(new InputStreamReader(System.in));

		// 字符流通向字節流
		BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(
				System.out));

		String s = null;
		while ((s = in.readLine()) != null) {
			if ("over".equals(s))
				break;
			bw.write(s.toUpperCase());// 寫入數據
			bw.newLine();// 換行
			bw.flush();// 刷新
		}
		bw.close();// 關閉流資源
		in.close();
	}
}

改變標準輸入輸出設備
System.setIn(InputStream in);// 改變標準輸入設備
System.setOut(PrintStream p);// 改變標準輸出設備
import java.io.*;
import java.text.*;
import java.util.*;
// 異常的日誌信息
class ExceptionInfo {
	public static void main(String[] args) {
		try {
			int[] arr = new int[2];
			System.out.println(arr[3]);
		} catch (Exception e) {
			try {
				Date d = new Date();// 創建時間對象
				// 時間模塊格式對象
				SimpleDateFormat sdf = new SimpleDateFormat(
						"yyyy年MM月dd日 HH:mm:ss");
				String s = sdf.format(d);

				PrintStream ps = new PrintStream("info.log");// 打印流對象
				System.setOut(ps);// 修改輸出流設備
				ps.println(s);// 輸出時間

			} catch (IOException ex) {
				throw new RuntimeException("文件創建失敗");
			}
			e.printStackTrace(System.out);// 將異常信息輸出指定輸出流
		}
	}
}

import java.util.*;
import java.io.*;

//將系統屬性信息保存到指定文本中
class SystemInfo {
	public static void main(String[] args) {
		PrintStream ps = null;
		try {
			// 獲取系統信息:
			Properties pop = System.getProperties();
			// 創建輸出流對象,將輸出流中數據存入指定文件中
			ps = new PrintStream("systeminfo.txt");
			// 將屬性列表輸出到指定的輸出流
			pop.list(ps);
		} catch (Exception e) {
			throw new RuntimeException("獲取系統信息失敗。");
		}
	}
}
發佈了46 篇原創文章 · 獲贊 0 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章