天天看點

I/O流_筆記I/O流

I/O流

I 是 input 輸入, O 是output輸出。

BIO

輸入輸出

CPU有輸入輸出、記憶體有輸入輸出、硬碟輸入輸出、網卡有輸入輸出…

每一個硬體都是以自己為基準。

JVM是一個程式,程式又都運作于記憶體之上。

I/O流_筆記I/O流

檔案操作

Java中需要使用 File 類來進行檔案的CURD操作。

File file = new File(檔案位址);
           

建立檔案

public static void create() throws IOException {
		File file = new File(位址);
		file.createNewFile();
}
           

删除檔案

public static void del() {
		File file = new File(檔案位址);
		file.delete();
}
           

擷取檔案夾下的檔案

public void show() {
        File files =new File("C:\\Users\\xing\\Desktop\\210901班級事宜");
        for(File file : files.listFiles()) {
        	System.out.println("file:"+file.getName());
        }
	}
           

輸入位元組流

第一步

打開一個檔案。

File file_read =new File(位址);
           
第二步

把檔案的内容輸入到記憶體。

InputStream fileInputStream = new FileInputStream(file_read);
           
第三步

建構一個數組,準備使用這個資料擷取輸入流中的資訊。

byte bytes[] = new byte[(int) file_read.length()];//拿到檔案的長度并且建立一個字元串
           
第四步

使用剛才準備的數組擷取輸入流的資料。

fileInputStream.read(bytes);//使用剛才的位元組組擷取檔案内容
           
第五步

輸出到控制台。

String str =new String(bytes);//把字元組轉換成String
System.out.println(str);
           
第六步

關閉。

fileInputStream.close();
           
案例
public void show1()   throws Exception{
				File file = new File("C:\\Users\\0924\\wenben.txt");
				FileInputStream fileInputStream = new FileInputStream(file);
				byte bytes[] = new byte[(int) file.length()];
				fileInputStream.read(bytes);
				String str =new String(bytes);//把字元組轉換成String
				System.out.println(str);
				fileInputStream.close();
	}
           

輸出位元組流

第一步

打開一個檔案。

File file = new File("C:\\Users\\xing\\0924\\wenben.txt");
           
第二步

建立一個輸出流,輸出至剛才的檔案。

FileOutputStream fileOutputStream = new FileOutputStream(file);
           
第三步

輸出内容至檔案。

String str =  "輸出這麼一句話!";
fileOutputStream.write(str.getBytes());
           
第四步

關閉

fileOutputStream.close();
System.out.println("輸出完畢!");
           
案例
public void show5()   throws Exception{
			File file = new File("C:\\Users\\xing\\0924\\wenben.txt");
			FileOutputStream fileOutputStream = new FileOutputStream(file);
			String str =  "輸出這麼一句話!";
			fileOutputStream.write(str.getBytes());
			fileOutputStream.close();
			System.out.println("輸出完畢!");
	}
           

拷貝檔案

第一步

下載下傳一個圖檔存在一個檔案夾。

第二步

建立一個File,使用這個 File 去讀取存放的檔案。

File file = new File("檔案存放位址");
           
第三步

擷取檔案的位元組輸入流。

InputStream fileInputStream = new FileInputStream(file);
           
第四步

建立一個數組使用數組擷取資料流的内容。

byte bytes[] = new byte[1024];
fileInputStream.read(bytes);
           
第五步

建立一個新的空的檔案。

File file_write =new File(具體檔案位址和名字);
           

注:同一個檔案夾下不能有同名的檔案

第六步

建立一個輸出流,并且準備把剛才讀取的資料輸出出去。

OutputStream outputStream = new FileOutputStream(file_write);//
outputStream.write(bytes);//使用剛才已經有内容的位元組組輸出
           
第七步

關閉

outputStream.close();
fileInputStream.close();
           

注:先開後關

字元流

字元流操作與位元組流類似。把位元組的操作換成字元的類即可,流程步驟都是位元組流的操作步驟。

public static void main(String[] args) throws Exception {
    InputStream inpu;
    char ch[] = new char[1024];
    Reader  reader = new FileReader("C:\\Users\\0924\\wenjian");
    reader.read(ch);
    Writer writer =new FileWriter("C:\\Users\\0924\\wenjian0");
    writer.write(ch);
    writer.close();
    reader.close();
}
           

基本緩沖操作

基礎

BufferedReader 是輸入緩沖字元流。

BufferedInputStream 是輸入緩沖位元組流。

BufferedWriter 是輸出緩沖字元流。

BufferedOutputStream 是輸出緩沖位元組流。

需要把對應的輸入\輸出流放到緩沖的構造方法中:

BufferedReader br = new BufferedReader(reader);
           
案例
/**
        * @time: 2021年9月26日上午9:59:30
        * @auth: xing
        * @return:void
        * @description:讀取緩沖
    */
	public static void main(String[] args) throws Exception {
        Reader  reader = new FileReader("C:\\Users\\0924\\wenjian");
        BufferedReader br = new BufferedReader(reader);
        String str = br.readLine();
        System.out.println(str);
        str = br.readLine();
        System.out.println(str);
        br.close();
        reader.close();
        //InputStream  fileInputStream = new FileInputStream("C:\\Users\0924\\wenjian");
        //BufferedInputStream bi = new BufferedInputStream(fileInputStream);

	}
           

NIO

概念

NIO是New I/O的簡稱,與舊式的基于流的I/O方法相對,從名字看,它表示新的一套Java I/O标 準。它是在Java 1.4中被納入到JDK中的,并具有以下特性:

  1. NIO是基于塊(Block)的,它以塊為基本機關處理資料 (硬碟上存儲的機關也是按Block來存儲,這樣性能上比基于流的方式要好一些)
  2. 為所有的原始類型提供(Buffer)緩存支援
  3. 增加通道(Channel)對象,作為新的原始 I/O 抽象
  4. 支援鎖(我們在平時使用時經常能看到會出現一些.lock的檔案,這說明有線程正在使用這把鎖,當線程釋放鎖時,會把這個檔案删除掉,這樣其他線程才能繼續拿到這把鎖)和記憶體映射檔案的檔案通路接口
  5. 提供了基于Selector的異步網絡I/O
I/O流_筆記I/O流

操作

  1. 得到Channel(管道)
  2. 申請Buffer(緩存空間)
  3. 建立Channel和Buffer的讀/寫關系
  4. 關閉
管道案例

使用50MB記憶體操作5G的檔案。

public static void main(String[] args) throws Exception {
				FileInputStream fin = new FileInputStream("D:\\迅雷下載下傳\\shipin.mkv");
				FileChannel fch =  fin.getChannel();
		
				FileOutputStream fou = new  FileOutputStream("C:\\Users\\xing\\Desktop\\222.mkv");
				FileChannel foh =fou.getChannel();
				ByteBuffer bf = ByteBuffer.allocateDirect(102400);
				
				int i = 0;
				while(true) {
					bf.clear();
					int r = fch.read(bf);
					bf.flip();
					if(r<0) {
						break;
					}
					foh.write(bf);
					Thread.sleep(1000);
					System.out.println("第:"+(++i));
				}
				fou.close();
				fin.close();
			}
           
緩存的三個辨別
public static void main(String[] args) throws Exception {
			//讀取檔案
			FileInputStream fin = new FileInputStream("C:\\Users\\xing\\Desktop\\建立文本文檔.txt");
			//建立通道
			FileChannel fch = fin.getChannel();		
			//建立一個容器10個長度
			ByteBuffer bf = ByteBuffer.allocate(10);
			output( "1", bf);		
			//讀取
			fch.read(bf);
			output( "2", bf);
			//開始
			bf.flip();
			output( "3", bf);
			//判斷是否還有資料可以讀取
			System.out.println("b:"+new String(bf.array()));
			output("4",bf);
			//清空
			bf.clear();
			output("5",bf);
			//關閉
			fin.close();
		}
           

AIO

AIO的特點:

  1. 讀完了再通知我
  2. 不會加快IO,隻是在讀完後進行通知
  3. 使用回調函數,進行業務處理

AIO的相關代碼:

AsynchronousServerSocketChannel

server = AsynchronousServerSocketChannel.open().bind( new InetSocketAddress (PORT));

使用server上的accept方法

server.accept(null,
    new CompletionHandler<AsynchronousSocketChannel, Object>() {
     final ByteBuffer buffer = ByteBuffer.allocate(1024);
  
     public void completed(AsynchronousSocketChannel result,
       Object attachment) {
      System.out.println(Thread.currentThread().getName());
      Future<Integer> writeResult = null;
      try {
       buffer.clear();
       result.read(buffer).get(100, TimeUnit.SECONDS);
       buffer.flip();
       writeResult = result.write(buffer);
      } catch (InterruptedException | ExecutionException e) {
       e.printStackTrace();
      } catch (TimeoutException e) {
       e.printStackTrace();
      } finally {
       try {
        server.accept(null, this);
        writeResult.get();
        result.close();
       } catch (Exception e) {
        System.out.println(e.toString());
       }
      }
     }
  
     @Override
     public void failed(Throwable exc, Object attachment) {
      System.out.println("failed: " + exc);
     }
    });
           

補充

注:由于LINUX對AIO的支援不好,是以AIO的使用并不多,大多數使用AIO的情況都是被Netty所替代。