流是一種抽象的概念,i/o流中的“i”代表“input”輸入,而“o”代表“output”輸出,io流可以理解為輸入輸出的途徑,如圖:

java中的io流是由四大抽象類組成:InputStream(位元組輸入流)、OutputStream(位元組輸出流)、Reader(字符輸入流)、Writer(字符輸出流)而這四大抽象類又有其相應的多種具體實作類,
java中的io流模型還用到了裝飾器模式,如圖:

現在就讓我來給大家教教這些流如何來使用,
一、檔案位元組流
首先,檔案位元組流分為輸出輸入兩類:FileInputStream、FileOutputStream,都是用位元組的形式對檔案進行位元組上的操作,
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class Test01{
public static void main(String[] args) {
try(FileInputStream fis = new FileInputStream("text.txt");
FileOutputStream fos = new FileOutputStream("text01.txt");){
int len = -1;
byte[] flush = new byte[1024];
while((len = fis.read(flush))!=-1) {
fos.write(flush, 0, len);
/*write和read的引數都是位元組或位元組陣列*/
String str = new String(flush);
System.out.print(str);
}
fos.flush();//完成寫入的操作后一定要重繪
}catch(IOException e) {
e.printStackTrace();
}
}
}
二、檔案字符流
檔案字符流與檔案位元組流最大的區別在于位元組流操作位元組或位元組陣列,而字符流操作字符或字符陣列,
即前者read/write方法引數為位元組或位元組陣列,后者read/write方法引數為字符或字符陣列,
同樣一個字符檔案,用位元組流可能會導致漢字亂碼問題,用字符流則不用擔心,
使用字符流完成剛才的代碼,只需要將位元組流換成字符流,位元組陣列換成字符陣列即可,如下:
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class Test01{
public static void main(String[] args) {
try(FileReader fr = new FileReader("text.txt");
FileWriter fw = new FileWriter("text01.txt");){
int len = -1;
char[] flush = new char[3];
while((len = fr.read(flush))!=-1) {
fw.write(flush, 0, len);
/*write和read的引數都是字符或字符陣列*/
String str = new String(flush);
System.out.print(str);
}
fw.flush();//完成寫入的操作后一定要重繪
}catch(IOException e) {
e.printStackTrace();
}
}
}
三、位元組陣列流
位元組陣列流與剛才介紹的兩種流的不同之處在于,他的輸入流構造器引數為位元組陣列,輸出流為空構造器,
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
public class Test01{
public static void main(String[] args) {
byte[] b = "Hello World!".getBytes();
try(ByteArrayInputStream bais = new ByteArrayInputStream(b);
ByteArrayOutputStream baos = new ByteArrayOutputStream();){
int len = -1;
byte[] flush = new byte[1024];
while((len=bais.read(flush))!=-1) {
baos.write(flush, 0, len);
}
baos.flush();
System.out.println(baos.toString()+"\n位元組數:"+baos.size());
}catch(IOException e) {
e.printStackTrace();
}
}
}
四、緩沖位元組流
從緩沖位元組流開始,下面介紹的一些流都屬于裝飾器模式中的具體裝飾類,
剛才我們在介紹“一、檔案位元組流”時用到的代碼,就可以用緩沖位元組流進行如下的裝飾,
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class Test01{
public static void main(String[] args) {
try(BufferedInputStream bis =
new BufferedInputStream(
new FileInputStream("text.txt"));
BufferedOutputStream bos =
new BufferedOutputStream(
new FileOutputStream("text01.txt"));){
int len = -1;
byte[] flush = new byte[1024];
while((len = bis.read(flush))!=-1) {
bos.write(flush, 0, len);
/*write和read的引數都是位元組或位元組陣列*/
String str = new String(flush);
System.out.print(str);
}
bos.flush();//完成寫入的操作后一定要重繪
}catch(IOException e) {
e.printStackTrace();
}
}
}
五、字符緩沖流
位元組緩沖流與字符緩沖流的區別類似于檔案位元組流和檔案字符流,
即前者操作位元組或位元組陣列,后者操作字符或字符陣列,
除此之外位元組緩沖流對應的具體組件是檔案位元組流,而字符緩沖流對應的具體組件是檔案字符流,
我們這里用到的例子一樣是在“二、檔案字符流”的例子的基礎上進行的修改,
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class Test01{
public static void main(String[] args) {
try(BufferedReader br =
new BufferedReader(
new FileReader("text.txt"));
BufferedWriter bw =
new BufferedWriter(
new FileWriter("text01.txt"));){
int len = -1;
char[] flush = new char[3];
while((len = br.read(flush))!=-1) {
bw.write(flush, 0, len);
/*write和read的引數都是字符或字符陣列*/
String str = new String(flush);
System.out.print(str);
}
bw.flush();//完成寫入的操作后一定要重繪
}catch(IOException e) {
e.printStackTrace();
}
}
}
六、資料流
其他幾種流中的資料都是位元組或字符的形式,而接下來介紹的資料流則是可以選定資料的格式并進行讀寫操作,無論字符資料,整形資料,位元組陣列資料,或是陣列,都可以利用資料流進行讀寫操作,
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class Test01{
public static void main(String[] args) {
try(DataInputStream dis =
new DataInputStream(
new FileInputStream("text.txt"));
DataOutputStream dos =
new DataOutputStream(
new FileOutputStream("text.txt"));){
dos.writeBoolean(false);
dos.writeChar('a');
dos.writeInt(12);
System.out.println(dis.readBoolean());
System.out.println(dis.readChar());
// System.out.println(dis.readChar());
/*第三個資料是整形資料,若將其按照字符型讀取,運行時會報錯*/
System.out.println(dis.readInt());
// System.out.println(dis.readInt());
/*資料已經讀取完了,再讀取必然會報錯*/
}catch(IOException e) {
e.printStackTrace();
}
}
}
七、物件流
物件流相當于是資料流的升級版,不僅可以讀寫資料流可以讀寫的資料型別,還能讀寫任何實作了反序列化的類,
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Date;
class Person{//Person類沒有實作反序列化
String name;
int id;
public Person(String name,int id) {
this.name = name;
this.id = id;
}
}
class Book implements Serializable{//Book類實作了反序列化
String name;
float price;
public Book(String name,float price){
this.name = name;
this.price = price;
}
}
public class Test01{
public static void main(String[] args) {
try(ObjectOutputStream oos=
new ObjectOutputStream(
new BufferedOutputStream(
new FileOutputStream("text.txt")))){
Date date = new Date();
Person person = new Person("spd",123456);
Book book = new Book("java程式基礎",38.8f);
oos.writeBoolean(false);
oos.writeChar('a');
oos.writeInt(12);
oos.writeObject("Hello World!");
oos.writeObject(date);
// oos.writeObject(person);
/*Person類沒有實作反序列化,因而不能使用writeObject方法進行寫入*/
oos.writeObject(book);
}catch(IOException e) {
e.printStackTrace();
}
}
}
八、轉換流
轉換流可以實作位元組流與字符流之間的轉換,
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
public class Test01{
public static void main(String[] args) {
try(BufferedReader br =
new BufferedReader(
new InputStreamReader(System.in));
BufferedWriter bw =
new BufferedWriter(
new OutputStreamWriter(System.out));){
/*無論是System.in還是System.out它們本身都不是字符流,*/
/*這里是利用了OutputStreamReader和InputStreamWriter對他們進行了轉換,*/
String str = new String();
while((str = br.readLine())!=null) {
bw.write(str);
bw.newLine();
bw.flush();
}
}catch(IOException e) {
e.printStackTrace();
}
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/256776.html
標籤:java
上一篇:逆向迷宮題總結(持續更新) 2020華南師大CTF新生賽maze,攻防世界新手區:NJUPT CTF 2017,BUUCTF:不一樣的flag
