1. 程式人生 > >java InputStream和OutputStream

java InputStream和OutputStream

InputStream Reader 是所有輸入流的基類。

本節內容:

目錄

InputStream

OutputStream

分割符的問題:

jdk7的改進寫法


InputStream

InputStream輸入流,以它的子類FileInputStream來講解

絕對路徑和相對路徑,

絕對路徑是值在硬碟上儲存的真正路徑

相對路徑 是指相對於某個檔案的路徑,

java讀取檔案時,系統預設從專案的根目錄開始讀取

InputStream抽象類中的常用方法:

  • int available() 返回可被讀取的位元組的長度
  •  close() 關閉流通道
  • int read() 從檔案中讀取一位元組內容,如果讀到內容,返回該位元組對應的ascii碼,可以通過轉成char型別列印該位元組的內容,中文的話會亂碼  ,如果讀不到內容,返回-1,讀完後指標移動到下個位置
  • int read(byte[] b) 每次從檔案中讀取一定數量的位元組放入byte陣列中,返回其讀到的位元組數目,如果沒有讀到內容,返回-1,讀到最後可能讀不滿,那麼最後一次讀取不會完全覆蓋之前的byte陣列,byte陣列中存放的是ascii碼可使用new String(byte[] b,int offset,int length)根據指定長度將byte陣列轉成字串,
  • int read(byte[] b, int off, int len)將指定長度的內容讀到byte陣列中,讀不到內容返回-1


 

import java.io.*;

public class IoTest01 {
      public static void main(String[] args){
          FileInputStream fi = null;
          try {
              //絕對路徑,加轉義字元防止路徑不正確
              fi=new FileInputStream("E:\\workspace\\javaIo\\test\\test1.txt");
                //相對路徑
               fi=new FileInputStream("./test/test1.txt");
               /*
              System.out.println(fi.read());//fi.read()每次讀取一位元組,然後遊標會移動到下一個
              System.out.println(fi.read());
              char c=(char)fi.read();//強轉為char型別,保證讀出來的不是ascii碼
              System.out.println(c);
              */
              //定義byte陣列每次讀取三個位元組提高效率
             /*  byte[] bytes=new byte[4];
               while (fi.read(bytes)!=-1){
                   System.out.println( new String(bytes));
               }*/
             byte[] bytes=new byte[4];
             int temp;
             while ((temp=fi.read(bytes))!=-1){
                 //new String (byte[],offset,len)將byte陣列按指定索引轉換成字串
               System.out.println(new String(bytes,0,temp) );
             }


          } catch (FileNotFoundException e) {
              e.printStackTrace();
          } catch (IOException e) {
              e.printStackTrace();
          }finally {
              try {
                  fi.close();
              } catch (IOException e) {
                  e.printStackTrace();
              }
          }

      }
}
out:
we m
ust 
stud
y ha
rd!

注意:程式中開啟的檔案 IO 資源不屬於記憶體裡的資源,垃圾回收機制無法回收該資源,所以應該顯式關閉檔案 IO 資源

OutputStream

OutputStream輸出流,它的常用子類如下

OutputStream抽象類中常用方法

  • void close()關閉輸出流,釋放系統資源
  • void flush()重新整理輸出流,保證快取中內容全部寫出去
  • void write(byte[] b) 一個bytes陣列通過輸出流寫入到輸出流
  • void write(byte[] b, int off, int len) 將指定起始位置和長度的byte陣列寫入到輸出流
  • Writes len bytes from the specified byte array starting at offset off to this output stream.
  • abstract void write(int b)寫一個byte到輸出流,int值的高24位(如果有)被忽略,將int的低8位轉換成ascii碼寫入

OutputStream的子類中常用的有FileOutputStream,它的構造方法有5個,常用的有

FileOutputStream(File file) 建立一個檔案輸出流,引數可以是檔案,也可以是字串形式的檔案地址
FileOutputStream(String name)
FileOutputStream(File file, boolean append)  建立一個檔案輸出流,第一個引數是檔名,可以是字串,第2個引數是否覆蓋檔案內容,如果為true在檔案內容的後面直接寫(要注意寫入換行符),不覆蓋原有內容,為false則覆蓋

FileOutputStream繼承自OutputStream,它的常用方法是重寫自父類的方法

注意如果該路徑檔案不存在,則自動建立該路徑下檔案

示例:

package io01;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class IoTest02 {
    public static void main(String[] args){
        FileOutputStream fo=null;
        try {
            fo=new FileOutputStream("test/test1.txt",true);
            fo.write(100);

            String msg="hello world";
            //呼叫字串的getBytes方法,將字串轉換為byte陣列
            fo.write(msg.getBytes());//write方法不會自動換行
            fo.write(msg.getBytes());//再寫一遍
            fo.write("\n".getBytes());//將換行符轉換成byte陣列,寫入到檔案中
            fo.write("javase".getBytes());
            //   重新整理以保證寫入
            fo.flush();

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                fo.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

分割符的問題:

在windows下路徑的分割符是\ ,還要防止轉義字元,出現轉義字元要多加一個\, 在linux下路徑分割符是/ ,為了保證程式碼的跨平臺執行,分割符可以使用File.separator來替代檔案路徑的分隔符,

fo=new FileOutputStream("test/test1.txt",true);
變成下面這種格式
fo=new FileOutputStream("test"+File.separator+"test1.txt",true);

io操作需要捕獲異常.因為不確定檔案到底是否存在,在try-catch-finally語句中,try語句塊宣告的變數不能在finally語句塊訪問,所以定義輸入輸出流時在try外部宣告,比如FileInputStream f=null

jdk7的改進寫法

jdk7之後,InputStream和OutputStream,Reader和Writer實現了Closeable介面,Closeable介面繼承自AutoCloseable介面,看下AutoCloseable介面的原始碼:

public interface AutoCloseable {
//AutoCloseable介面只有一個close抽象方法,
    void close() throws Exception;
}
從jdk7之後不需要手動關閉io流了,因為io流都實現了close方法,建立io流物件後,會自動呼叫這個方法,寫法變成了將輸出流的初始化放到try後面的小括號中,不需要在finally語句塊中呼叫流物件的close方法

示例

//將test/test.txt檔案中的內容打印出來
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class File7 {
    public static void main(String[] args){
        try (
                FileInputStream fis=new FileInputStream("test"+ File.separator+"test.txt");
                                                                                          ){
            int temp;
            while((temp=fis.read())!=-1){
                System.out.println( (char)temp);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

 

參考: http://www.monkey1024.com/javase/602