2017 - 10 -28 IO流 數據操作流 內存操作流 打印流 標準輸入輸出流 隨機訪問流 序列化流

1 操作基本數據類型的流
可以讀寫基本數據類型的數據
數據輸入流:DataInputStream
               DataInputStream(InputStream in)
數據輸出流:DataOutputStream
               DataOutputStream(OutputStream out)

public class DataStreamDemo {
public static void main(String[] args) throws IOException {
// 寫
// write();
// 讀
read();
}

private static void read() throws IOException {
// DataInputStream(InputStream in)
// 創建數據輸入流對象
DataInputStream dis = new DataInputStream(
new FileInputStream("dos.txt"));
// 讀數據
byte b = dis.readByte();
short s = dis.readShort();
int i = dis.readInt();
long l = dis.readLong();
float f = dis.readFloat();
double d = dis.readDouble();
char c = dis.readChar();
boolean bb = dis.readBoolean();
// 釋放資源
dis.close();
System.out.println(b);
System.out.println(s);
System.out.println(i);
System.out.println(l);
System.out.println(f);
System.out.println(d);
System.out.println(c);
System.out.println(bb);
}

private static void write() throws IOException {
// DataOutputStream(OutputStream out)
// 創建數據輸出流對象
DataOutputStream dos = new DataOutputStream(new FileOutputStream(
"dos.txt"));
// 寫數據了
dos.writeByte(10);
dos.writeShort(100);
dos.writeInt(1000);
dos.writeLong(10000);
dos.writeFloat(12.34F);
dos.writeDouble(12.56);
dos.writeChar('a');
dos.writeBoolean(true);
// 釋放資源
dos.close();
}
}

2 內存操作流
內存操作流:用於處理臨時存儲信息的,程序結束,數據就從內存中消失。
字節數據:
    ByteArrayInputStream
    ByteArrayOutputStream
字符數組:
    CharArrayReader
    CharArrayWriter
字符串:
    StringReader 
    StringWriter

public class ByteArrayStreamDemo {
public static void main(String[] args) throws IOException {
// 寫數據
// ByteArrayOutputStream()
ByteArrayOutputStream baos = new ByteArrayOutputStream();

// 寫數據
for (int x = 0; x < 10; x++) {
baos.write(("hello" + x).getBytes());
}

// 釋放資源
// 通過查看源碼我們知道這裏什麼都沒做,所以根本需要close()
// baos.close();

// public byte[] toByteArray()
byte[] bys = baos.toByteArray();

// 讀數據
// ByteArrayInputStream(byte[] buf)
ByteArrayInputStream bais = new ByteArrayInputStream(bys);

int by = 0;
while ((by = bais.read()) != -1) {
System.out.print((char) by);
}

// bais.close();
}
}

3 打印流
字節流打印流  PrintStream
字符打印流    PrintWriter
打印流特點:
    A:只有寫數據的,沒有讀取數據。只能操作目的地,不能操作數據源。
    B:可以操作任意類型的數據。
    C:如果啓動了自動刷新,能夠自動刷新。
    D:該流是可以直接操作文本文件的。
       哪些流對象是可以直接操作文本文件的呢?
         FileInputStream
FileOutputStream
FileReader
FileWriter
PrintStream
PrintWriter
  看API,查流對象的構造方法,如果同時有File類型和String類型的參數,一般來說就是可以直接操作文件的。
      
         流:
基本流:就是能夠直接讀寫文件的
高級流:在基本流基礎上提供了一些其他的功能
----------------------------------------------------------
// 作爲Writer的子類使用
PrintWriter pw = new PrintWriter("pw.txt");
pw.write("hello");
pw.write("world");
pw.write("java");
pw.close();
----------------------------------------------------------
PrintWriter實現自動刷新和換行
1:可以操作任意類型的數據。
         print()
         println()
2:啓動自動刷新(調用帶ln的方法才行)
      PrintWriter pw = new PrintWriter(new FileWriter("pw2.txt"), true);
      還是應該調用println()的方法纔可以
      這個時候不僅僅自動刷新了,還實現了數據的換行。
           println()
  其實等價于于:
    bw.write();
    bw.newLine();
    bw.flush();
          // 創建打印流對象
 // PrintWriter pw = new PrintWriter("pw2.txt");
    PrintWriter pw = new PrintWriter(new FileWriter("pw2.txt"), true);//啓動自動刷新
          // write()是搞不定的,怎麼辦呢?
 // 我們就應該看看它的新方法
 // pw.print(true);
 // pw.print(100);
 // pw.print("hello");
    pw.println("hello");
    pw.println(true);
    pw.println(100);
    pw.close();
4 打印流實現文本複製

需求:DataStreamDemo.java複製到Copy.java中
數據源:
    DataStreamDemo.java -- 讀取數據 -- FileReader -- BufferedReader
目的地:
    Copy.java -- 寫出數據 -- FileWriter -- BufferedWriter -- PrintWriter

public class CopyFileDemo {
public static void main(String[] args) throws IOException {
// 以前的版本
// 封裝數據源
// BufferedReader br = new BufferedReader(new FileReader(
// "DataStreamDemo.java"));
// // 封裝目的地
// BufferedWriter bw = new BufferedWriter(new FileWriter("Copy.java"));
//
// String line = null;
// while ((line = br.readLine()) != null) {
// bw.write(line);
// bw.newLine();
// bw.flush();
// }
//
// bw.close();
// br.close();

// 打印流的改進版
// 封裝數據源
BufferedReader br = new BufferedReader(new FileReader(
"DataStreamDemo.java"));
// 封裝目的地
PrintWriter pw = new PrintWriter(new FileWriter("Copy.java"), true);
String line = null;
while((line=br.readLine())!=null){
pw.println(line);
}
pw.close();
br.close();
}
}

5 標準輸入輸出流
System類中的兩個成員變量:
public static final InputStream in "標準"輸入流
public static final PrintStream out "標準"輸出流

InputStream is = System.in;
PrintStream os = System.out;

System.out.println("helloworld");
//獲取標準輸出流對象
PrintStream ps = System.out;
ps.println("helloworld");//以前講的輸出語句其實就是IO流操作,把數據輸出到控制檯

ps.println();
//ps.print();//這個方法不存在
//System.out.println();
//System.out.print();

6 三種方式實現鍵盤錄入
System.in 標準輸入流,是從鍵盤獲取數據的

鍵盤錄入數據:
     A:main方法的args接收參數。
         java HelloWorld hello world java 
     B:Scanner(JDK5以後的)
         Scanner sc = new Scanner(System.in);
         String s = sc.nextLine();
         int x = sc.nextInt();
     C:通過字符緩衝流包裝標準輸入流實現
         BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

public class SystemInDemo {
public static void main(String[] args) throws IOException {
// //獲取標準輸入流
// InputStream is = System.in;
// //我要一次獲取一行行不行呢?
// //行。
// //怎麼實現呢?
// //要想實現,首先你得知道一次讀取一行數據的方法是哪個呢?
// //readLine()
// //而這個方法在哪個類中呢?
// //BufferedReader
// //所以,你這次應該創建BufferedReader的對象,但是底層還是的使用標準輸入流
// // BufferedReader br = new BufferedReader(is);
// //按照我們的推想,現在應該可以了,但是卻報錯了
// //原因是:字符緩衝流只能針對字符流操作,而你現在是字節流,所以不能是用?
// //那麼,我還就想使用了,請大家給我一個解決方案?
// //把字節流轉換爲字符流,然後在通過字符緩衝流操作
// InputStreamReader isr = new InputStreamReader(is);
// BufferedReader br= new BufferedReader(isr);
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

System.out.println("請輸入一個字符串:");
String line = br.readLine();
System.out.println("你輸入的字符串是:" + line);

System.out.println("請輸入一個整數:");
// int i = Integer.parseInt(br.readLine());
line = br.readLine();
int i = Integer.parseInt(line);
System.out.println("你輸入的整數是:" + i);
}
}

7 隨機訪問流

RandomAccessFile類不屬於IO流,是Object類的子類。
但它融合了InputStream和OutputStream的功能。
支持對文件的隨機訪問讀取和寫入。

public RandomAccessFile(String name,String mode):第一個參數是文件路徑,第二個參數是操作文件的模式。
模式有四種,我們最常用的一種叫"rw",這種方式表示我既可以寫數據,也可以讀取數據 
------------------------------------------
public class RandomAccessFileDemo {
public static void main(String[] args) throws IOException {
// write();
read();
}

private static void read() throws IOException {
// 創建隨機訪問流對象
RandomAccessFile raf = new RandomAccessFile("raf.txt", "rw");

int i = raf.readInt();
System.out.println(i); // 100
// 該文件指針可以通過 getFilePointer方法讀取,並通過 seek 方法設置。
System.out.println("當前文件的指針位置是:" + raf.getFilePointer()); //當前文件的指針位置是:4  (int 4)

char ch = raf.readChar();
System.out.println(ch);
System.out.println("當前文件的指針位置是:" + raf.getFilePointer());//當前文件的指針位置是:6 (char 2 +4)

String s = raf.readUTF();
System.out.println(s);
System.out.println("當前文件的指針位置是:" + raf.getFilePointer()); ////當前文件的指針位置是:14 ( 6+6(UTF的兩個漢字) +2(readUTF後面要加2個。。。))

// 我不想重頭開始了,我就要讀取a,怎麼辦呢?
raf.seek(4);
ch = raf.readChar();
System.out.println(ch); // 6
}

private static void write() throws IOException {
// 創建隨機訪問流對象
RandomAccessFile raf = new RandomAccessFile("raf.txt", "rw");

// 怎麼玩呢?
raf.writeInt(100);
raf.writeChar('a');
raf.writeUTF("中國");
raf.close();
}
}

8 合併流
以前的操作:
a.txt -- b.txt
c.txt -- d.txt
現在想要:
a.txt+b.txt -- c.txt
(1)
// SequenceInputStream(InputStream s1, InputStream s2)
// 需求:把ByteArrayStreamDemo.java和DataStreamDemo.java的內容複製到Copy.java中

InputStream s1 = new FileInputStream("ByteArrayStreamDemo.java");
InputStream s2 = new FileInputStream("DataStreamDemo.java");
SequenceInputStream sis = new SequenceInputStream(s1, s2);
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("Copy.java"));
// 如何寫讀寫呢,其實很簡單,你就按照以前怎麼讀寫,現在還是怎麼讀寫
byte[] bys = new byte[1024];
int len = 0;
while ((len = sis.read(bys)) != -1) {
bos.write(bys, 0, len);
}

bos.close();
sis.close();

(2)
// 需求:把下面的三個文件的內容複製到Copy.java中
//ByteArrayStreamDemo.java,CopyFileDemo.java,DataStreamDemo.java
       // SequenceInputStream(Enumeration e)
// 通過簡單的回顧我們知道了Enumeration是Vector中的一個方法的返回值類型。
// Enumeration<E> elements()
Vector<InputStream> v = new Vector<InputStream>();
InputStream s1 = new FileInputStream("ByteArrayStreamDemo.java");
InputStream s2 = new FileInputStream("CopyFileDemo.java");
InputStream s3 = new FileInputStream("DataStreamDemo.java");
v.add(s1);
v.add(s2);
v.add(s3);
Enumeration<InputStream> en = v.elements();
SequenceInputStream sis = new SequenceInputStream(en);
BufferedOutputStream bos = new BufferedOutputStream(
new FileOutputStream("Copy.java"));

// 如何寫讀寫呢,其實很簡單,你就按照以前怎麼讀寫,現在還是怎麼讀寫
byte[] bys = new byte[1024];
int len = 0;
while ((len = sis.read(bys)) != -1) {
bos.write(bys, 0, len);
}

bos.close();
sis.close();

9 序列化流
序列化流:把對象按照流一樣的方式存入文本文件或者在網絡中傳輸。對象 -- 流數據(ObjectOutputStream)
反序列化流:把文本文件中的流對象數據或者網絡中的流對象數據還原成對象。流數據 -- 對象(ObjectInputStream)
public class ObjectStreamDemo {
public static void main(String[] args) throws IOException,
ClassNotFoundException {
// 由於我們要對對象進行序列化,所以我們先自定義一個類
// 序列化數據其實就是把對象寫到文本文件
// write();
read();
}

private static void read() throws IOException, ClassNotFoundException {
// 創建反序列化對象
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("oos.txt"));

// 還原對象
Object obj = ois.readObject();

// 釋放資源
ois.close();

// 輸出對象
System.out.println(obj);
}

private static void write() throws IOException {
// 創建序列化流對象
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(
"oos.txt"));

// 創建對象
Person p = new Person("林青霞", 27);

// public final void writeObject(Object obj)
oos.writeObject(p);

// 釋放資源
oos.close();
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章