天天看點

fileoutputstream 檔案不存在_Java檔案操作,IO操作

fileoutputstream 檔案不存在_Java檔案操作,IO操作
命裡有時終須有,命裡無時莫強求。

簡介

  • IO操作是指Input、Output,資料的輸入與輸出,主要是操作資料:
    • Input指的是從資料源讀取資料到記憶體,例如:把資料從磁盤上讀取到記憶體中,從網絡讀取資料到記憶體中等等。
    • Output值得是把資料輸出到其他地方,例如:把資料寫入到檔案,把資料輸出到網絡等等。
  • Java中把檔案中的内容讀取到記憶體叫做輸入流InputStream,而把資料寫入到檔案中叫做輸出OutputStream,這是最基本的兩種IO流

同步和異步

  • 同步是指讀寫IO的操作完成以後才能完成其他任務,優點是編寫簡單,缺點是執行效率低
  • 異步是指讀寫IO的操作的同僚可以完成其他任務,優點是執行效率高,缺點是編寫複雜
  • java.io

    提供同步IO
  • java.nio

    提供異步IO

File對象

  • java.io

    中提供了檔案操作類File,使用構造方法建立一個File對象,即使檔案或者目錄不存在也不會報錯,因為這個時候并不會操作磁盤,隻有調用File對象的具體方法時候才會進行磁盤操作
public class DemoController {
   public static void main(String[] args){
     File f = new File("C:javahello.java");
     System.out.println(f); // C:javahello.java
   }
 }
           
  • getPath(),該方法傳回構造方法傳入的路徑,原封不動的傳回
public class DemoController {
   public static void main(String[] args){
     File f = new File(".javahello.java");
     System.out.println(f.getPath()); // .javahello.java
   }
 }
           
  • getAbsolutePath(),該方法傳回的是絕對路徑,拼接上完整的路徑但是不幫着處理. ..符号(.表示目前目錄 ..表示上級目錄)
public class DemoController { 
   public static void main(String[] args){
      File f = new File(".javahello.java");
      System.out.println(f.getAbsolutePath()); // E:javaProjectstudy.javahello.java
   }
 }
           
  • getCanonicalPath(),該方法傳回的是處理好的規範路徑
public class DemoController {
   public static void main(String[] args) throws IOException {
     File f = new File(".javahello.java");
     System.out.println(f.getCanonicalPath()); // E:javaProjectstudyjavahello.java
   }
 }
           
  • separator 可以列印對應系統下的路徑分隔符
public class DemoController {
   public static void main(String[] args) {
     System.out.println(File.separator); // windows   linux /
   }
 }
           
  • isFile() 判斷檔案是否存在
  • isDirectory() 判斷檔案目錄是否存在
  • canRead() 是否可讀
  • canWrite() 是否可寫
  • canExecute() 是否可執行 如果是目錄則表示能否顯示所有的檔案和子目錄
  • length() 檔案位元組大小
  • createNewFile() 建立一個新檔案
  • delete() 删除檔案
  • createTempFile() 建立臨時檔案,與deleteOnExit()在JVM退出時删除改檔案,兩者關聯使用
  • list()和listFiles() 列出目錄下面所有檔案和子目錄名,listFiles提供了很多重載方法,可以過濾檔案和目錄
  • mkdir() 建立目錄
  • mkdirs() 建立目錄,如果父目錄不存在也會建立
  • delete() 删除目錄,目錄必須為空才能删除成功

Path對象

  • Path位于Java.nio.file包。Path對象和File對象差不多
  • Paths.get(".","father","children"...) 建立一個Path對象
  • toAbsolutePath() 轉化為絕對路徑
  • normalize() 轉化為規範路徑
  • toFile() 轉化為File對象

InputStream

  • InputSteam是一個抽象類,FileInputStream是InputSteam的子類
public static void readFile() throws IOException {
   InputStream inputStream = null;
   try{
     inputStream = new FileInputStream("E:javaProjectstudystudy-20-8-30srcDemo05readme.txt"); // 檔案裡面寫Hello World!, 檔案可以儲存任意地方
     int n;
     while((n = inputStream.read()) != -1){
       System.out.println((char) n);
     }
   } finally {
     inputStream.close(); // 關閉流,必須用完就關閉流
   }
 }
           

緩沖

  • 上面的read雖然可疑讀取檔案内容,但是一次隻能讀取一個位元組,并不是很高效,可以通過InputSteam中的重載方法來讀取多個位元組
public static void readMoreFile() throws IOException {
   InputStream inputStream = null;
   byte[] bytes = new byte[1000];
   try{
     inputStream = new FileInputStream("E:javaProjectstudystudy-20-8-30srcDemo05readme.txt");
     int n;
     while((n = inputStream.read(bytes)) != -1){
       System.out.println(n);
     }
   } finally {
     inputStream.close(); // 關閉流
   }
 }
           

阻塞

  • 阻塞的意思就是有任務在執行,卡在那不往後面執行,比如在執行read()方法的時候就需要等待read()方法傳回後才能執行下面的代碼

模拟InputStream

  • 可以使用

    ByteArrayInputStream

    僞造一個資料流
public static void makeSteam () throws IOException {
   byte[] data = { 72, 101, 108, 108, 111, 33 };
   try (InputStream inputStream = new ByteArrayInputStream(data)) {
     int n;
     while ((n = inputStream.read()) != -1) {
       System.out.println((char) n);
     }
   }
 }
           

OutputStream

  • 與InputStream相反,OutputStream是輸出流的超類,也是抽象類。
  • OutputSteam也提供了

    close()

    方法關閉輸出流,還提供了一個

    flush()

    方法,作用是将内容真正輸出到目的地,通常情況不需要調用這個人方法,因為OutputStream會自動調用,如果需要在某些特定情況主動推送緩存發送就需要主動觸發flush
public static void fileOutput() throws IOException {
  FileOutputStream fileOutputStream = new FileOutputStream("E:javaProjectstudystudy-20-8-30srcDemo05readme.txt");
	// 寫入 wirte方法也是阻塞的
  fileOutputStream.write(72); // H
  fileOutputStream.write(101); // e
  fileOutputStream.write(108); // l
  fileOutputStream.write(108); // l
  fileOutputStream.write(111); // o
  fileOutputStream.close();
  // 或者通過write的重載方法 與InputStream一樣,為了避免IO錯誤導緻資源沒有關閉,通常需要用try...finally
  try (OutputStream fileOutputStream2 = new FileOutputStream("E:javaProjectstudystudy-20-8-30srcDemo05readme.txt")){
    fileOutputStream.write("Hello".getBytes("UTF-8")); // Hello
  } finally {
    fileOutputStream.close();
  }
}
           
  • FileOutputStream是OutputStream的一個實作類,可以從檔案中擷取輸出流。與InputStream一樣,ByteArrayOutputStream可以再記憶體中模拟一個OutputStream輸出流
public static void makeOutput () throws IOException {
  byte[] data;
  ByteArrayOutputStream outputStream = null;
  try {
    outputStream = new ByteArrayOutputStream();
    outputStream.write("Hello".getBytes());
    data = outputStream.toByteArray();
  } finally {
    outputStream.close();
  }
  System.out.println(new String(data, "UTF-8"));
}
           

操作zip

  • 讀取zip使用ZipInputStream
public static void getZip() throws  IOException {
  ZipInputStream zipInputStream = null;
  try{
    zipInputStream = new ZipInputStream(new FileInputStream("E:javaProjectstudystudy-20-8-30srcDemo05Demo05.zip"));
    ZipEntry entry = null;
    // 判斷是否還有檔案
    while ((entry = zipInputStream.getNextEntry()) != null){
      String name = entry.getName(); // 擷取檔案名字
      System.out.println(name);
      if (!entry.isDirectory()){
        int n;
        while ((n = zipInputStream.read()) != -1){
          System.out.println((char) n);
        }
      }
    }
  }finally {
    zipInputStream.close();
  }
}
           
  • 寫入zip包時使用的是ZipOutputStream
public static void setZip() throws IOException {
   ZipOutputStream zipOutputStream = null;
   try {
     zipOutputStream = new ZipOutputStream(new FileOutputStream("E:javaProjectstudystudy-20-8-30srcDemo05Demo05.zip"));
     ArrayList<File> files = new ArrayList<>();
     files.add(new File("E:javaProjectstudystudy-20-8-30srcDemo05readme.txt"));
     files.add(new File("E:javaProjectstudystudy-20-8-30srcDemo05readme - 副本.txt"));
     for (File file : files) {
       zipOutputStream.putNextEntry(new ZipEntry(file.getName()));
       zipOutputStream.write(getFileToByte(file));
       zipOutputStream.closeEntry();
     }
   }finally {
     zipOutputStream.close();
   }
 }
public static byte[] getFileToByte(File file) {
  byte[] by;
  try {
    InputStream inputStream = new FileInputStream(file);
    ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
    byte[] bb = new byte[2048];
    int ch;
    ch = inputStream.read(bb);
    while (ch != -1) {
      byteArrayOutputStream.write(bb, 0, ch);
      ch = inputStream.read(bb);
    }
    by = byteArrayOutputStream.toByteArray();
  } catch (Exception ex) {
    throw new RuntimeException("transform file into bin Array 出錯",ex);
  }
  return by;
}
           

Reader與Writer

  • 如果是讀寫字元,比如純文字的資料源,可以使用Reader和Writer進行讀和寫的操作,這種流成為字元流,資料源雖然是位元組的,但是Reader和Writer内部進行了處理,将byte做了解碼轉化為char
  • FileReader是Reader的一個子類,FileReader可以打開一個檔案并讀取
public static void readerReadFile() throws IOException {
  Reader reader = null;
  try{
    reader = new FileReader("E:javaProjectstudystudy-20-8-30srcDemo05readme.txt");
    int n;
    while((n = reader.read()) != -1){
      System.out.println((char) n);
    }
  }finally {
    reader.close();
  }
}
           
  • CharArrayReader可以通過傳入一個char[]模拟一個Reader
Reader reader = new CharArrayReader("Hello".toCharArray);
           
  • StringReader 可以通過傳入一個String 模拟一個StringReader
Reader reader = new StringReader("Hello")
           
  • InputStreamReader可以通過傳入一個InputStream轉為一個Reader
Reader reader = new InputStreamReader(new FileInputStream("XXX"),"UTF-8");
           
  • FileWriter可以項檔案中寫入字元流
Writer writer = new FileWriter("XXX");
wirter.wirter("asdas");
           
  • CharArrayWriter可以在記憶體中建立一個Writer,作用就是狗在一個一個緩沖區
public static void wirterFile() {
  try (CharArrayWriter writer = new CharArrayWriter()) {
    writer.write(72); // H
    writer.write(101); // e
    writer.write(108); // l
    writer.write(108); // l
    writer.write(111); // o
    char[] data = writer.toCharArray();
    System.out.println(new String(data));
  }
}
           
  • StringWriter也是一個機遇記憶體的writer和CharArrayWriter類似
  • OutPutStreamWriter可以講一個FileOutputStream流轉化為Writer

本文作者《猿氏·凱》,如果雷同,純屬抄襲····