親愛的樂字節的小夥伴們,小樂又來分享Java技術文章了。上一篇寫到了IO流,這篇文章着重 談談輸入流,再下次再說輸出流。
一、 輸入流
字節流和字符流的操作方式幾乎完全一樣,只是操作的數據單元不同而已 。字節流可
以操作所有文件,字符流僅操作純文本。
1、抽象類:InputStream 和 Reader
InputStream和Reader是所有輸入流的基類,它們是兩個抽象類,是所有輸入流的模版,其中定義的方法在所有輸入流中都可以使用。
在InputStream裏包含如下三個方法:
在Reader中包含如下三個方法:
對比InputStream和Reader 所提供的方法,可以看出這兩個基類的功能基本相似。返回結果爲-1 時表明到了輸入流的結束點。 InputStream 和 Reade 都是抽象的,不能直接創建它們的實例,可以使用它們的子類。
2、文件節點類: FileInputStream 和 FileReader
FileInputStream 和 FileReader,它們都是節點流,直接和指定文件關聯。 操作方式
基本一致。
1)、單個字節讀取
以FileInputStream爲例:
public class SingleFileRead {
public static void main(String[] args) {
// 1、建立聯繫 File對象
File file = new File("f:/IO/test.txt");
// 2、選擇流
InputStream in = null;// 提升作用域
try {
in = new FileInputStream(file);
// 3、操作 單個字節讀取
long fileLength = file.length(); // 接收實際讀取的字節數
// 計數器
System.out.println(fileLength);
long num = 0;
// 循環讀取
while (num < fileLength) {
char ch = (char) in.read();
System.out.println(ch);
num++;
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println("文件不存在,不能進行下一步操作");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println("讀取文件失敗");
} finally {
try {
// 4、釋放資料
if (in != null) {
in.close();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println("關閉文件輸入流失敗");
}
}
}
}
2)、批量讀取(字節|字符重點)
public class ReadFile {
public static void main(String[] args) {
//1、字節讀取:建立聯繫 File對象
File file=new File("f:/IO/test.txt");
//2、選擇流
InputStream in=null;//提升作用域
try {
in=new FileInputStream(file);
//3、操作 不斷讀取 緩衝數組
byte[]car=new byte[1024];
int len=0; //接收實際讀取的大小
//循環讀取
while(-1!=(len=in.read(car))){
//輸出,字節數組轉成字符串
String info=new String(car,0,len);
System.out.println(info);
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println("文件不存在");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println("讀取文件失敗");
}finally{
try {
//4、釋放資料
if(in!=null){
in.close();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println("關閉文件輸入流失敗");
}
}
}
}
//字符讀取1、創建源
File src=new File("f:/char.txt");
//2、選擇流
Reader reader=new FileReader(src);
//3、讀取操作
char[] flush=new char[1024];
int len=0;
while(-1!=(len=reader.read(flush))){
//字符數組轉換爲字符串
String str=new String(flush,0,len);
System.out.println(str);
}
//4、釋放資源
reader.close();
樂字節原創
3、緩衝處理類:BufferedInputStream和 BufferedReader(重點)
緩衝提高性能: 字節流直接套上即可;字符緩衝流 +新增方法(不能使用多態)
//1、創建源,建立聯繫
File src =new File("test.txt");
//2、選擇緩衝流
InputStream is =new BufferedInputStream(new FileInputStream(src)); //3、操作 : 多個讀取
byte[] car =new byte[2];
int len =0;
while(-1!=(len=is.read(car))){
//獲取數組的內容 字節數組轉字符串 new String(字節數組,0,length)
System.out.println(new String(car,0,len));
}
//4、釋放資源
is.close();
//創建源:
File src =new File("test.txt");
//使用字符緩衝流 提高性能讀取文件 +新增方法(不能使用多態)
BufferedReader br =new BufferedReader(new FileReader(src));
//操作 行讀取
String line=null;
while(null!=(line=br.readLine())){
System.out.println(line);
}
//釋放資源
br.close();
4、轉換處理流: InputStreamReader
轉換流:將字節流轉爲字符流 處理亂碼(編碼集、解碼集)。
//讀取文件
File src =new File("test.txt");
//轉換流
BufferedReader br =new BufferedReader(
new InputStreamReader(
new BufferedInputStream(
new FileInputStream(
src
)
),"utf-8"
)
);
//行讀取
String msg =null;
while(null!=(msg =br.readLine())){
System.out.println(msg);
}
br.close();
5、字節數組節點類: ByteArrayInputStream
操作的節點爲字節數組,數組在jvm 內存中,由垃圾回收機制管理,不需要手動關閉
//1、創建源
byte[] src ="io 學習入門".getBytes();
//2、選擇流
InputStream is = new ByteArrayInputStream(src);
//3、操作 與文件一致
byte[] flush =new byte[10];
int len =0;
while(-1!=(len =is.read(flush))){
System.out.println(new String(flush,0,len));
}
//4、釋放
is.close();
6、數據處理流:DataInputStream
可以處理基本類型+String,保留數據的類型。前提是讀取順序與寫出順序一致,否則讀取數據不正確
/**
* 數據+類型 輸出到文件
* @param destPath
* @throws IOException
*/
public static void write(String destPath) throws IOException{
int point=2;
long num=100L;
String str="數據類型";
//創建源
File dest=new File(destPath);
//選擇流
DataOutputStream dos=new DataOutputStream(new BufferedOutputStream(new FileOutputStream(dest)));
//操作 寫出的順序 爲讀取作準備
dos.writeInt(point);
dos.writeLong(num);
dos.writeUTF(str);
dos.flush();
//釋放資源
dos.close();
}
7、對象處理流(反序列化):ObjectInputStream
/**
* 反序列化:
* 1、先寫入再讀取
* 2、讀取對象需要知道具體類型,依次讀取
* 注意:
* 1)不是所有的對象都可以序列化 Serializable
* 2)不是所有的屬性都需要序列化 transient
*/
public static void read(String srcPath) throws FileNotFoundException, IOException, ClassNotFoundException{
//創建源
File src=new File(srcPath);
//選擇流 OjbectInputStream
ObjectInputStream dis=new ObjectInputStream(
new BufferedInputStream(
new FileInputStream(src)
)
);
//操作 讀取的順序與寫出的順序一致 必須存在才能讀取
Object obj=dis.readObject();
if(obj instanceof Employee){
Employee emp=(Employee)obj;
System.out.println(emp.getName());
System.out.println(emp.getSalary());
}
obj=dis.readObject();
int[]arr=(int[])obj;
System.out.println(Arrays.toString(arr));
//釋放資源
dis.close();
}
Java中的IO流-輸入流就介紹到這裏了,下次再說輸出流。
樂字節原創,更多Java技術乾貨持續更新,歡迎關注。