鍍金池/ 教程/ Java/ Java通道
Java文件屬性
Java FilePermission示例
Java Externalizable實(shí)例
Java文件操作
Java文件鎖
Java文件系統(tǒng)
Java異步I/O
Java Reader/Writer
Java File實(shí)例
Java FileReader示例
Java控制臺(tái)
Java文件所有者權(quán)限
Java通道
Java ByteArrayOutputStream示例
BufferedOutputStream示例
Java FileInputStream示例
Java DataInputStream
Java BufferedInputStream
Java Jar Manifest
Java Console類示例
BufferedWriter示例
Java輸入/輸出教程
Java對(duì)象序列化
Java文件教程
Java DataInputStream類型
Java Zip字節(jié)數(shù)組
Java FileWriter示例
FileOutputStream示例
Java PrintStream
Java Scanner類
BufferedInputStream示例
Java字符集
ByteArrayInputStream示例
Java路徑操作
Java DataOutputStream
Java符號(hào)鏈接
Java FilterWriter示例
Java Jar API
BufferedReader實(shí)例
Java Pipe(管道)
Java jar文件
Java CharArrayReader示例
Java CharArrayWriter示例
Java PushbackInputStream
Java FilterReader示例
Java zip文件
Java InputStream
Java標(biāo)準(zhǔn)輸入/輸出/錯(cuò)誤流
Java文件內(nèi)容和讀寫
Java FilterInputStream示例
Java內(nèi)存通道
Java路徑
Java令牌和字符串拆分
Java隨機(jī)訪問(wèn)文件
Java文件樹
Java緩沖區(qū)讀寫
Java FileOutputStream
Java目錄事件
Java FilterOutputStream示例
Java DataOutputStream實(shí)例
FileDescriptor示例

Java通道

通道(Channel)是數(shù)據(jù)源和Java程序之間的開放連接,用于執(zhí)行I/O操作。Channel接口在java.nio.channels包中。通道(Channel)接口只聲明了兩個(gè)方法:close()isOpen()。

各種渠道

ReadableByteChannel用于使用read()方法將數(shù)據(jù)從數(shù)據(jù)源讀取到字節(jié)緩沖區(qū)中。WritableByteChannel用于使用write()方法將數(shù)據(jù)從字節(jié)緩沖區(qū)寫入數(shù)據(jù)宿。

ByteChannel能夠分別使用read()write()方法讀取和寫入字節(jié)數(shù)據(jù)。ScatteringByteChannel將數(shù)據(jù)從數(shù)據(jù)源讀取到多個(gè)字節(jié)緩沖區(qū)中。 從已知的文件格式或類似的數(shù)據(jù)源讀取數(shù)據(jù)是有用的,其中在一些固定長(zhǎng)度的報(bào)頭中提供數(shù)據(jù),隨后是可變長(zhǎng)度的主體。

GatheringByteChannel從多個(gè)字節(jié)緩沖區(qū)中寫出數(shù)據(jù)。

創(chuàng)建通道

要獲得一個(gè)通道,舊的方式使用java.io包中的類I/O來(lái)創(chuàng)建InputStreamOutputStream的對(duì)象。
java.nio.channels包中的Channels類是一個(gè)實(shí)用程序類,它有許多靜態(tài)方法將流轉(zhuǎn)換為通道,反之亦然。

Channels類還提供了將讀寫器轉(zhuǎn)換為通道的方法,反之亦然。例如,如果有一個(gè)名為myInputStream的輸入流對(duì)象,獲得一個(gè)ReadableByteChannel如下:

ReadableByteChannel rbc  = Channels.newChannel(myInputStream);

如果有一個(gè)名為rbcReadableByteChannel,可以獲得如下的基本InputStream對(duì)象:

InputStream myInputStream  = Channels.newInputStream(rbc);

FileInputStreamFileOutputStream類有一個(gè)稱為getChannel()的新方法來(lái)返回一個(gè)FileChannel對(duì)象。FileChannel用于讀取和寫入數(shù)據(jù)到文件。從FileInputStream獲取的FileChannel對(duì)象以只讀模式打開。

FileInputStream fis  = new FileInputStream("test1.txt"); 
FileChannel fcReadOnly  = fis.getChannel(); // A  read-only  channel

FileOutputStream對(duì)象獲取的FileChannel對(duì)象以只寫模式打開。

FileOutputStream fos   = new FileOutputStream("test1.txt"); 
FileChannel  fcWriteOnly = fos.getChannel(); // A  write-only  channel

如果從RandomAccessFile獲取一個(gè)FileChannel,它將以只讀,只寫或讀寫模式打開,這取決于創(chuàng)建RandomAccessFile對(duì)象的方式。
以下代碼為不同種類的文件流獲取FileChannel對(duì)象:

// read-only mode
RandomAccessFile  raf1 = new RandomAccessFile("test1.txt", "r"); 
FileChannel  rafReadOnly = raf1.getChannel(); // A  read-only  channel

// read-write mode
RandomAccessFile  raf2 = new RandomAccessFile("test1.txt", "rw"); 
FileChannel rafReadWrite = raf2.getChannel(); // A  read-write channel

讀/寫文件

FileChannel對(duì)象維護(hù)位置變量作為緩沖區(qū)。FileChannelread()write()方法有兩種類型:相對(duì)位置讀/寫和絕對(duì)位置讀/寫。

當(dāng)打開一個(gè)FileChannel時(shí),它的位置設(shè)置為0,這是文件的開始。當(dāng)使用相對(duì)read()方法從FileChannel讀取時(shí),它的位置增加讀取的字節(jié)數(shù)。
FileChannel讀取的絕對(duì)位置不會(huì)影響其位置??梢允褂?code>position()方法獲取FileChannel對(duì)象的當(dāng)前位置值。使用position(int newPosition)方法將其位置設(shè)置為新位置。

通道也是可自動(dòng)關(guān)閉的。如果使用try-with-resources語(yǔ)句來(lái)獲得一個(gè)通道,通道將被自動(dòng)關(guān)閉,這樣就不用顯示地調(diào)用通道的close()方法。

以下代碼從名為test1.txt的文件中讀取文本。

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

public class Main {
  public static void main(String[] args) {
    File inputFile = new File("test1.txt");
    if (!inputFile.exists()) {
      System.out.println("The input file " + inputFile.getAbsolutePath()
          + "  does  not  exist.");
      System.out.println("Aborted the   file reading process.");
      return;
    }
    try (FileChannel fileChannel = new FileInputStream(inputFile).getChannel()) {
      ByteBuffer buffer = ByteBuffer.allocate(1024);
      while (fileChannel.read(buffer) > 0) {
        buffer.flip();
        while (buffer.hasRemaining()) {
          byte b = buffer.get();
          System.out.print((char) b);
        }
        buffer.clear();
      }
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
}

上面的代碼生成以下結(jié)果。

The input file F:\website\yiibai\worksp\test1.txt  does  not  exist.
Aborted the   file reading process.

示例

以下代碼顯示如何使用緩沖區(qū)和通道寫入文件。

import java.io.File;
import java.nio.channels.FileChannel;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.io.FileOutputStream;

public class Main {
  public static void main(String[] args) {
    File outputFile = new File("test.txt");

    try (FileChannel fileChannel = new FileOutputStream(outputFile)
        .getChannel()) {
      String text = getText();
      byte[] byteData = text.toString().getBytes("UTF-8");
      ByteBuffer buffer = ByteBuffer.wrap(byteData);
      fileChannel.write(buffer);
    } catch (IOException e1) {
      e1.printStackTrace();
    }
  }

  public static String getText() {
    String lineSeparator = System.getProperty("line.separator");
    StringBuilder sb = new StringBuilder();
    sb.append("test");
    sb.append(lineSeparator);
    sb.append("test");
    sb.append(lineSeparator);

    sb.append("test");
    sb.append(lineSeparator);
    sb.append("test");

    return sb.toString();
  }
}

復(fù)制文件的內(nèi)容

可以使用緩沖區(qū)和通道來(lái)復(fù)制文件。獲取源文件和目標(biāo)文件的FileChannel對(duì)象,并對(duì)源FileChannel對(duì)象調(diào)用transferTo()方法或調(diào)用目標(biāo)FileChannel對(duì)象上的transferFrom()方法。
以下代碼顯示如何復(fù)制文件。

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.nio.channels.FileChannel;

public class Main {
  public static void main(String[] args) throws Exception {

    FileChannel sourceChannel = new FileInputStream("sourceFile").getChannel();
    FileChannel sinkChannel = new FileOutputStream("newFile").getChannel();

    // Copy source file contents to the sink file
    sourceChannel.transferTo(0, sourceChannel.size(), sinkChannel);
  }
}

上一篇:Java FilterReader示例下一篇:Java Jar API