首页 > 编程语言 >JAVA基础-IO

JAVA基础-IO

时间:2024-02-19 10:47:32浏览次数:34  
标签:JAVA io read 基础 write IO println new out

1,IO 概念

IO 通常表示计算机与外界数据的输入与输出。I/O 流:IO流又叫输入输出流 ,输入和输出均是以内存作为参照物

分类:

1)按照流的方向

以内存为参考物,往内存中去,叫做输入,从内存中出来,叫做输出。

2)按照读取数据方式

字节流,一次读取一个字节 byte
字符流,一次读取一个字符,具体几个字节取决于编码,只能处理文本文件。

3)按功能

节点流:可以从一个特定数据源读写数据,如 FileInputStream, FileReader
处理流(包装流):链接已存在的流之上,为程序停工更为强大的读写功能。处理流只需要关闭自己,内部的流不用关。

2,BIO

1,四大家族:

  • java.io.InputStream 字节输入流
  • java.io.OutputStream 字节输出流
  • java.io.Reader 字符输入流
  • java.io.Writer 字符输出流

2,IO 流特征

1)所有的流都实现了 java.io.Colseable接口,都是可关闭的,都有close()方法. 流毕竟是一个管道,这个是内存和硬盘之间的通道,养成一个好习惯,用完流将其关闭
2)所有的输出流都实现了 java.io.Flushable接口,都是可刷新的,都有flush()方法,这个刷新表示将通道/管道当中剩余未输出的数据强行输出完(清空管道!)刷新的作用就是清空管道。如果没有flush()可能会导致数据丢失.
3)在java中只要"类名"以Stream结尾的都是字节流。以"Reader/Writer"结尾的都是字符流

3,16个流需要掌握

1)文件专属

java.io.FileinputStream (用得最多)
/**
 * FileInputStream
 * 文件字节输入流,万能的,任何类型的文件都可以采用这个流来读
 * 字节的方式,完成输入的操作,完成读的操作(硬盘 —> 内存)
 *
 * 方法:
 * read() 读取一个字节,返回的是读取到的内容的 int 表示,返回 -1 表示没有读到。
 * read(byte[] b) 读取一个指定数组大小的内容,将读取内容放到 byte 数组中。返回 -1 说明没有读取到任何内容。
 * read(byte[] b, int off, int len) 读取 len 长度的字节,从数组的 off 位置开始填充数组
 * */
@Test
public void FileInputStream() throws IOException {
    FileInputStream fis = new FileInputStream("D:\\gaox\\files\\test\\io_demo\\fileInputStream.txt");

    byte[] by = new byte[4];
    int length;
    while((length = fis.read(by)) != -1){
        System.out.println(new String(by, 0, length));
    }
    fis.close();
}
java.io.FileOutputStream (用得最多)
/**
 * FileOutputStream
 * 文件字节输出流,负责写,从内存到硬盘
 * 构造方法:
 * FileOutputStream(String name, boolean append)  第二个参数表示追加。如果根据文件路径找不到文件,就会自己创建一个文件
 *
 * 方法:
 * write(int) 写入一个数字
 * write(byte[] c) 写入一个字节数组
 * <!---->write(byte[] c, int off, int len) 从数组 c 的 off 位置开始写入 len 个字节
 * flush() 刷新
 * */
@Test
public void FileOutputStream() throws IOException {
    FileOutputStream fos = new FileOutputStream("D:\\gaox\\files\\test\\io_demo\\fileOutputStream.txt");
    fos.write("yanqishiwode".getBytes(), 1, 10);
    fos.flush();
    fos.close();
}
java.io.FileReader
/**
 * FileReader
 * 文件字符输入流,以字符 char 为单位,只能读文本
 *
 * 方法:
 * getEncoding():获取编码
 * read():读取一个字符,返回 int 类型,可以强转成 char, -1 表示没读到
 * read(char[] c):读取字符数组长度的字符,然后填充到数组 c 中, -1 表示没读到,返回值为实际读的数据
 * read(char[] c, int off, int len) 读取 len 长度的字符,放到从 off 开始的数组 c 中,-1表示没读到返回值为实际读到的数据
 * */
@Test
public void FileReader() throws IOException {
    FileReader fr = new FileReader("D:\\gaox\\files\\test\\io_demo\\fileReader.txt");
    System.out.println((char)fr.read());
    System.out.println(fr.read());

    char[] chars = new char[10];
    fr.read(chars);
    System.out.println(chars);

    //读取部分,chars 数组其他位置仍然是上面读取的内容
    fr.read(chars, 4, 3);
    System.out.println(chars);

    int len;
    while((len = fr.read(chars)) != -1){
        System.out.println(len);
    }

    fr.close();
}
java.io.FileWriter
/**
 * FileWriter
 * 文件字符输出流,以字符 char 为单位
 *
 * 方法:
 * write():输出一个字符
 * write(char[] c):输出整个字符数组
 * write(char[] c, int off, int len):输入数组 c 中,从 off 开始共计 len 长度的字符
 * write(String s):输出字符串
 * write(String s, int off, int len):输出字符串的一部分
 * flush() 刷新
 * */
@Test
public void fileWriter() throws IOException {
    FileWriter fw = new FileWriter("D:\\gaox\\files\\test\\io_demo\\fileWriter.txt", true);
    fw.write(49);
    char[] chr = new char[]{'张','非','又','要','大','人','了'};
    fw.write(chr);
    fw.write(chr, 1, 3);

    fw.write("张三");
    fw.write("woaiyanqi", 3, 5);

    fw.flush();
    fw.close();
}

2)转换流 (将字节流转换成字符流)

InputStreamReader
/**
 * InputStreamReader
 * 输入转换流:将字节流转换为字符流
 *
 * 构造方法
 * InputStreamReader(InputStream in); 入参一个字节流,返回一个 inputStreamReader 转换流,该流是字符流
 *
 * read 三个 read 方法跟 reader 保持一致
 *
 *
 * */
@Test
public void InputStreamReader() throws IOException {
    InputStreamReader isr = new InputStreamReader(new FileInputStream("D:\\gaox\\files\\test\\io_demo\\fileInputReader.txt"));
    System.out.println((char)isr.read());

    char[] chr = new char[10];
    System.out.println(isr.read(chr));
    System.out.println(chr);

    chr = new char[10];
    System.out.println(isr.read(chr, 3,7));
    System.out.println(chr);

    isr.close();
}
outputStreamWriter
/**
   * outputStreamWriter
   * 输出转换流
   *
   * write 五个方法与 fileWriter 五个 write 方法一致
   * */
  @Test
  public void outputStreamWriter() throws IOException {
      OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("D:\\gaox\\files\\test\\io_demo\\outputStreamWriter.txt", true));
      //osw.write
      osw.write(49);

      osw.write(new char[]{'y','a','n','q','i'});

      osw.write("不服来战");

      osw.write(new char[]{'y','a','n','q','i'}, 1, 3);

      osw.write("hello world", 1, 3);

      osw.flush();
      osw.close();
  }

3)缓冲流专属: 缓冲流相比普通的流,多出一个缓冲区,可以读取比规定的多的数据,减少 io 次数,这类流构造方法都有个参数规定缓冲区大小

BufferedReader
/**
   * BufferedReader
   * 缓冲输入字符流
   *
   * 构造方法:
   * BufferedReader(Reader r, int size)  size 缓冲区大小
   *
   * 方法:
   * read 常规三个方法
   * readLine() 读一行
   * */
  @Test
  public void bufferedReader() throws IOException {
      BufferedReader br = new BufferedReader(new FileReader("D:\\gaox\\files\\test\\io_demo\\bufferedReader.txt"),1);
      System.out.println( (char)br.read());

      char[] chr = new char[10];
      br.read(chr);
      System.out.println(chr);

      chr = new char[10];
      br.read(chr, 1, 5);
      System.out.println(chr);

      String s = br.readLine();
      System.out.println(s);
      br.close();
  }
bufferedWriter
 /**
     * bufferedWriter
     * 缓冲字符输出流
     *
     * 构造方法:
     * BufferedWriter(Writer out)
     *
     * 方法:
     * write 五个常规方法
     * newLine() 创建新的一行
     *
     * */
    @Test
    public void bufferedWriter() throws IOException {
        BufferedWriter bw = new BufferedWriter(new FileWriter("D:\\gaox\\files\\test\\io_demo\\bufferedWriter.txt"));
        bw.write(49);
        bw.write(new char[]{'1','2'});
        bw.newLine();
        bw.write("woaiyanqi");
        bw.flush();
        bw.close();
    }
BufferedInputStream
/**
 * BufferedInputStream
 * 字节缓冲输入流
 *
 * 构造方法:
 * BufferedInputStream(InputStream i);
 *
 * 方法:
 * read() 的三个方法
 * */
@Test
public void bufferedInputStream() throws IOException {
    BufferedInputStream bis = new BufferedInputStream(new FileInputStream("D:\\gaox\\files\\test\\io_demo\\bufferInputStream.txt"));
    System.out.println( bis.read() );

    byte[] b = new byte[10];
    bis.read(b);
    System.out.println(b);

    bis.read(b, 1, 9);
    System.out.println(b);
    bis.close();
}
BufferedOutputStream
/**
 * BufferedOutputStream
 *
 * 构造方法
 * BufferedOutputStream(OutputStream os)
 *
 * 方法
 * write() 三个方法
 * */
@Test
public void bufferedOutputStream() throws IOException {
    BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("D:\\gaox\\files\\test\\io_demo\\bufferedOutputStream.txt"));
    bos.write(49);

    String str = "wohao稀饭ya#@  &*qia";

    bos.write(str.getBytes());
    bos.write(str.getBytes(), 1, 10);
    bos.flush();
    bos.close();
}

4)数据流

DataOutputStream
/**
 * DataOutputStream
 * 数据输出流
 *
 * 构造方法
 * DataOutputStream(OutputStream os)
 *
 * 方法:
 * write() 三件套
 * writeInt() 等八大类型
 * */
@Test
public void dataOutputStream() throws IOException {
    DataOutputStream dos = new DataOutputStream(new FileOutputStream("D:\\gaox\\files\\test\\io_demo\\dataInputStream.txt"));
    dos.writeChar('燕');
    dos.writeInt(112);
    dos.writeDouble('燕');
    dos.flush();
    dos.close();
}
DataInputStream
/**
 * DataInputStream
 * 数据输入流:只能读 DataOutputStream() 写入的数据,并且需要知道顺序
 *
 * 构造方法:
 * DataInputStream(InputStream is)
 *
 * 方法:
 * read() 三件套
 * readInt() 等八大类型
 * */
@Test
public void dataInputStream() throws IOException {
    DataInputStream dis = new DataInputStream(new FileInputStream("D:\\gaox\\files\\test\\io_demo\\dataInputStream.txt"));
    System.out.println( dis.readChar() );
    System.out.println(dis.readInt());
    System.out.println(dis.readDouble());
    dis.close();
}

5)标准输出流

PrintStream
/**
 * printStream
 * 标准输出流
 *
 * System.out、System.err 等返回的就是 printStream
 * */
@Test
public void printStream() throws FileNotFoundException {

    //默认输出到控制台
    PrintStream out = System.out;
    out.println("yanqi");
    out.println("nidei");
    out.println("shenmedeganh");

    //输出到日志去
    PrintStream ps = new PrintStream(new FileOutputStream("D:\\gaox\\files\\test\\io_demo\\log.txt"));
    System.setOut(ps);
    ps.println("张三");
    System.out.println("你跑哪去了");
}
PrintWriter 不知道咋用

6)对象专属流

ObjectOutputStream
/**
 * ObjectOutputStream
 * 对象输出流,配合序列化
 * */
@Test
public void objectOutputStream() throws IOException {
    ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("D:\\gaox\\files\\test\\io_demo\\objectOutputStream.txt"));
    oos.writeObject(new Cat("yanqi", 25, "white"));
    oos.writeObject(new Cat("yanqi", 26, "white"));
    oos.writeObject(new Cat("yanqi", 27, "white"));
    oos.writeObject(new Cat("yanqi", 28, "white"));
    oos.writeObject("张三");
    oos.writeObject(new Cat("yanqi", 29, "white"));
    oos.flush();
    oos.close();
}
ObjectInputStream
/**
 * ObjectInputStream
 * 对象输入流,配合序列化
 * */
@Test
public void ObjectInputStream() throws IOException, ClassNotFoundException {
    ObjectInputStream ois = new ObjectInputStream(new FileInputStream("D:\\gaox\\files\\test\\io_demo\\objectOutputStream.txt"));
    System.out.println(ois.readObject());
    System.out.println(ois.readObject());
    System.out.println(ois.readObject());
    System.out.println(ois.readObject());
    System.out.println(ois.readObject());
    System.out.println(ois.readObject());
    ois.close();
}

4,文件操作 demo

字节流复制文件
/**
 * 字节流复制文件
 * */
@Test
public void fileCopy() {
    try(
        //卸载这里,会自动关闭流
        FileInputStream fis = new FileInputStream("D:\\gaox\\files\\test\\io_demo\\bizhi.rar");
        FileOutputStream fos = new FileOutputStream("D:\\gaox\\files\\test\\copy_io_demo\\bizhi.rar")
    ){
        byte[] byt = new byte[1024];
        int len;
        while( (len = fis.read(byt)) != -1 ){
            //这里因为最后可能数组都不满,所以每次只需要将有数据的写入文件就好了
            fos.write(byt, 0, len);
        }
        fos.flush();
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}
字符流复制文件:只能复制文本
/**
 * 字符流复制文件:只能复制文本
 * */
@Test
public void copyFileByChar(){
    try( FileReader fr = new FileReader("D:\\gaox\\files\\test\\io_demo\\catalina.out");
         FileWriter fw = new FileWriter("D:\\gaox\\files\\test\\copy_io_demo\\catalina.txt")
    ){
        char[] chr = new char[10];
        int len;
        while( (len = fr.read(chr)) != -1 ){
            fw.write(chr, 0, len);
        }
        fw.flush();
    }catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

5,压缩流

ZipInputStream,ZipOutputStream,ZipFile,ZipEntry 等。

压缩流 demo
/**
 * ZipOutputStream
 * 压缩流:单个文件压缩
 * */
@Test
public void zipFile() throws IOException {

    //要压缩的文件
    File file = new File("D:\\gaox\\files\\test\\io_demo\\catalina.out");
    //压缩后的压缩包
    File zipFile = new File("D:\\gaox\\files\\test\\io_demo\\catalina.zip");

    FileInputStream fs = new FileInputStream(file);
    ZipInputStream zis = new ZipInputStream(fs);
    ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(zipFile));

    zos.putNextEntry(new ZipEntry(file.getName()));

    byte[] byt = new byte[1024];
    int len;
    while( (len = fs.read(byt)) != -1 ){
        zos.write(byt, 0, len);
    }
    zos.close();
    zis.close();
}

/**
 * ZipOutputStream
 * 压缩流:文件夹压缩
 * */
@Test
public void zipFiles() throws IOException {
    //要压缩的文件夹
    File file = new File("D:\\gaox\\files\\test\\io_demo");
    //压缩后的压缩包
    File zipFile = new File("D:\\gaox\\files\\test\\copy_io_demo\\io_demo.zip");
    
    //定义文件输入流
    InputStream is;
    
    //定义输出压缩流
    ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(zipFile));
    zos.setComment("yanqi");

    recursionZip(zos, file, "");
    zos.close();
}

//压缩方法抽出
private void recursionZip(ZipOutputStream zos, File file, String baseDir) throws IOException {
    byte[] byt = new byte[1024];
    int len;

    if(file.isDirectory()){
        //如果是文件夹,获取文件夹下所有文件
        File[] files = file.listFiles();
        for(File item : files){
            recursionZip(zos, item, baseDir + File.separator + file.getName());
        }
    }else{
        //对文件做压缩处理
        FileInputStream is = new FileInputStream(file);
        zos.putNextEntry(new ZipEntry(baseDir + File.separator + file.getName()));

        while(( len = is.read(byt)) != -1){
            zos.write(byt, 0, len);
        }
        is.close();

    }
}

/**
 * 解压缩
 * ZipFile
 * */
@Test
public void unzip() throws IOException {

    //压缩包
    File inFile = new File("D:\\gaox\\files\\test\\copy_io_demo\\io_demo.zip");
    ZipFile zipFile = new ZipFile(inFile);

    //解压后的文件路径
    String path = inFile.getParent();

    //压缩输入流
    ZipInputStream zis = new ZipInputStream(new FileInputStream(inFile));

    ZipEntry entity;
    while( (entity = zis.getNextEntry()) != null ){
        System.out.println("解压缩:" + entity.getName());

        File outFile = new File(path + File.separator + entity.getName());
        if( !outFile.getParentFile().exists() ){
            outFile.getParentFile().mkdir();
        }
        outFile.createNewFile();

        InputStream is = zipFile.getInputStream(entity);
        FileOutputStream fos = new FileOutputStream(outFile);

        byte[] byt = new byte[1024];
        int len;
        while( (len = is.read(byt)) != -1 ){
            fos.write(byt, 0, len);
        }
        is.close();
        fos.close();
    }
}

3,NIO

1,NIO 简介

  nio:new io,也称为非阻塞 io。与原来的 io 有同样的作用和目的,但是使用方式完全不同。

  NIO支持面向缓冲区的、基于通道的IO操作。NIO将以更加高效的方式进行文件的读写操作。NIO可以理解为非阻塞IO,传统的IO的read和write只能阻塞执行,线程在读写IO期间不能干其他事情,比如调用socket.read()时,如果服务器一直没有数据传输过来,线程就一直阻塞,而NIO中可以配置socket为非阻塞模式

2,NIO 特点

1)NIO相关类都被放在java.nio包及子包下,并且对原java.io包中的很多类进行改写。

2)NIO有三大核心部分:Channel(通道),Buffer(缓冲区), Selector(选择器)

3)Java NlO的非阻塞模式,使一个线程从某通道发送请求或者读取数据,但是它仅能得到目前可用的数据,如果目前没有数据可用时,就什么都不会获取,而不是保持线程阻塞,所以直至数据变的可以读取之前,该线程可以继续做其他的事情。非阻塞写也是如此,一个线程请求写入一些数据到某通道,但不需要等待它完全写入,这个线程同时可以去做别的事情。

4)通俗理解:NIO是可以做到用一个线程来处理多个操作的。假设有1000个请求过来,根据实际情况,可以分配20或者80个线程来处理。不像之前的阻塞IO那样,非得分配1000个。

3,nio 和 io 比较

1)BIO以流的方式处理数据,而NIO以块的方式处理数据,块I/O的效率比流IO高很多

2)BIO是阻塞的,NIO则是非阻塞的(Java NIO 的非阻塞,是相对于连接的非阻塞,而不是指方法调用时的非阻塞)

3)BlO基于字节流和字符流进行操作,而NIO基于Channel(通道)和Buffer(缓冲区)进行操作,数据总是从通道读取到缓冲区中,或者从缓冲区写入到通道中。Selector(选择器)用于监听多个通道的事件(比如:连接请求,数据到达等),因此使用单个线程就可以监听多个客户端通道

4,NIO 三要素

1),Buffer 缓冲区

  java.nio.Buffer 缓冲区本质上是一块可以写入数据,然后可以从中读取数据的内存。这块内存被包装成NIO Buffer对象,并提供了一组方法,用来方便的访问该块内存。相比较直接对数组的操作,Buffer APl更加容易操作和管理。

  nio 面向块,这个块就是 Buffer

2). Channel 通道
  通道(Channel):由 java.nio.channels 包定义 的。Channel 表示 IO 源与目标打开的连接。 Channel 类似于传统的“流”。只不过 Channel 本身不能直接访问数据,Channel 只能与 Buffer 进行交互

3),Selector 选择器
  选择器(Selector)是SelectableChannle对象的多路复用器,Selector可以同时监控多个SelectableChannel的IO状况,也就是说,利用Selector可使一个单独的线程管理多个Channel。Selector是非阻塞IO的核心

5,NIO demo

public class DemoMain {

    /**
     * nio 写本地文件
     * */
    @Test
    public void write() throws IOException {
        FileOutputStream fos = new FileOutputStream("D:\\gaox\\files\\日志\\copy.txt");
        FileChannel channel = fos.getChannel();

        ByteBuffer buf = ByteBuffer.allocate(1024);
        buf.put("yanqinidenalipaowl来两个中文ogaodingnil".getBytes());
        buf.flip();
        channel.write(buf);
        buf.clear();
        channel.close();
    }

    /**
     * nio 读本第文件
     * */
    @Test
    public void read() throws IOException {
        FileInputStream fis = new FileInputStream("D:\\gaox\\files\\日志\\test.log");
        FileChannel chl = fis.getChannel();

        int bufLength = 1024;
        ByteBuffer buf = ByteBuffer.allocate(bufLength);
        byte[] bytes = new byte[bufLength];

        int read;
        while( (read = chl.read(buf)) != -1){
            buf.flip();
            buf.get(bytes, 0 , read);
            System.out.println(new String(bytes));
            buf.clear();
        }
        chl.close();
    }

    /**
     * 使用 buffer复制
     * */
    @Test
    public void bufferCopy() throws IOException {
        FileChannel fic = new FileInputStream("D:\\gaox\\files\\日志\\catalina1231231241231312311312414.out").getChannel();
        FileChannel foc = new FileOutputStream("D:\\gaox\\files\\日志\\bufferCopy.out").getChannel();

        ByteBuffer buf = ByteBuffer.allocate(1024);
        while(fic.read(buf) != -1){
            buf.flip();
            foc.write(buf);
            buf.clear();
        }
        fic.close();
        foc.close();
    }

    /**
     * transferFrom 复制
     * */
    @Test
    public void transferFrom() throws IOException {
        FileChannel fic = new FileInputStream("D:\\gaox\\files\\日志\\catalina1231231241231312311312414.out").getChannel();
        FileChannel foc = new FileOutputStream("D:\\gaox\\files\\日志\\bufferCopy1.out").getChannel();

        foc.transferFrom(fic, fic.position(), fic.size());
        fic.close();
        foc.close();
    }

    /**
     * transferTo 复制
     * */
    @Test
    public void transferTo() throws IOException {
        FileChannel fic = new FileInputStream("D:\\mySoftWare\\jdk-17_windows-x64_bin.zip").getChannel();
        FileChannel foc = new FileOutputStream("D:\\mySoftWare\\jdk-17_windows-x64_bi1n1.zip").getChannel();

        long l = fic.transferTo(fic.position(), fic.size(), foc);
        System.out.println("传输完成!");
        fic.close();
        foc.close();
    }

    /**
     * 案例6-分散 (Scatter) 和聚集 (Gather)
     * */
    @Test
    public void test() throws IOException{
        RandomAccessFile raf1 = new RandomAccessFile("D:\\gaox\\files\\日志\\catalina1231231241231312311312414.out", "rw");
        //1. 获取通道
        FileChannel channel1 = raf1.getChannel();

        //2. 分配指定大小的缓冲区
        ByteBuffer buf1 = ByteBuffer.allocate(100);
        ByteBuffer buf2 = ByteBuffer.allocate(1024);

        //3. 分散读取
        ByteBuffer[] bufs = {buf1, buf2};
        channel1.read(bufs);

        for (ByteBuffer byteBuffer : bufs) {
            byteBuffer.flip();
        }

        System.out.println(new String(bufs[0].array(), 0, bufs[0].limit()));
        System.out.println("-----------------");
        System.out.println(new String(bufs[1].array(), 0, bufs[1].limit()));

        //4. 聚集写入
        RandomAccessFile raf2 = new RandomAccessFile("D:\\gaox\\files\\日志\\bufferCopy3.out", "rw");
        FileChannel channel2 = raf2.getChannel();

        channel2.write(bufs);
    }

}

6,I/O 多路复用技术

  在传统的IO编程中,每个socket连接都需要一个线程或进程来处理,这样就会导致系统资源的浪费和性能问题。而IO多路复用则可以通过一个线程或进程来同时管理多个socket连接,并且可以同时处理多个连接上的IO事件。

  常用的IO多路复用技术有select、poll、epoll等。

  以select为例,当一个进程调用select函数时,它会将多个文件描述符注册到一个监控集合中,并设置监听事件类型(如可读、可写、异常等)。然后,select函数会阻塞进程,直到监控集合中的任意一个文件描述符发生了监听事件(读、写)。此时,select函数就会返回,并告诉进程哪些文件描述符有事件发生,进程可以根据返回值来处理相应的IO事件。

7,Reactor 模式

  Reactor 设计模式就是基于建立连接与具体服务之间线程分离的模式。在 Reactor 模式中,会有一个线程负责与所有客户端建立连接,这个线程通常称之为 Reactor。然后在建立连接之后,Reactor 线程 会使用其它线程(可以有多个)来处理与每一个客户端之间的数据传输,这个(些)线程通常称之为 Handler

4,AIO

1,简介

AIO,异步非阻塞 IO,又称 NIO2.0,最大的一个特性就是异步能力,这种能力对socket与文件I/O都起作用。AIO其实是一种在读写操作结束之前允许进行其他操作的I/O处理。

2,AIO demo

/**
 *
 *   AsynchronousSocketChannel
 * ​ AsynchronousServerSocketChannel
 * ​ AsynchronousFileChannel
 * ​ AsynchronousDatagramChannel
 * */
public class AioDemo {

    @Test
    public void test() throws IOException, ExecutionException, InterruptedException {
        AsynchronousFileChannel channel = open(Paths.get("D:\\gaox\\files\\模型\\科艺楼.安装模型 - 副本.zip"), StandardOpenOption.READ);

        ByteBuffer byteBuffer = ByteBuffer.allocate(1024 * 1024 * 1024);
        Future<Integer> read = channel.read(byteBuffer, 0);

        System.out.println("读了,但是不知道有没有读出来!");
        read.get();
        byteBuffer.flip();
        System.out.println("读出来了:" + byteBuffer.get());
    }


}

5,参考文献

JAVA-IO详解

java之NIO简介

Java NIO 中的非阻塞究竟体现在哪里

标签:JAVA,io,read,基础,write,IO,println,new,out
From: https://www.cnblogs.com/cnff/p/17528938.html

相关文章

  • JAVA基础-SPI
    1,什么是SPISPI全名ServiceProviderinterface,翻译过来就是“服务提供接口”,再说简单就是提供某一个服务的接口,提供给服务开发者或者服务生产商来进行实现。JavaSPI是JDK内置的一种动态加载扩展点的实现。这个机制在一般的业务代码中很少用到(个人接触到的业务没有用到过),但是......
  • JAVA基础-反射
    1,什么是反射?  Java反射就是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;并且能改变它的属性。而这也是Java被视为动态(或准动态,为啥要说是准动态,因为一般而言的动态语言定义是程序运行时,允许改变程序结构或变量类......
  • JAVA基础-泛型
    1,泛型概述泛型,即“参数化类型”。一提到参数,最熟悉的就是定义方法时有形参,然后调用此方法时传递实参。那么参数化类型怎么理解呢?顾名思义,就是将类型由原来的具体的类型参数化,类似于方法中的变量参数,此时类型也定义成参数形式(可以称之为类型形参),然后在使用/调用时传入具体的类型......
  • JAVA基础-序列化
    1,什么是序列化?Java序列化是指把Java对象转换为字节序列的过程,而Java反序列化是指把字节序列恢复为Java对象的过程。2,序列化的使用场景永久性保存对象,保存对的字节序列到本地文件或者数据库中;通过序列化以字节流的形式对象在网络中进行传递和接收;通过序列化在进程间传递......
  • JAVA基础-Steam
    1,OptionalJava8中的Optional是一个可以包含或不可以包含非空值的容器对象。1.1,获取Optional的三个方法1.of(value)返回一个Optional,value不可以为null2.empty()返回一个空的Optional3.ofNullable(value)返回一个Optional,如果value为null,就是empty(),否......
  • JAVA基础-类加载过程
    1,类的加载1,类的加载过程2,加载阶段通过一个类的全限定名获取定义此类的二进制字节流将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构在内存中生成一个代表这个类的java.lang.Class对象,作为方法区这个类的各种数据的访问入口加载class文件的方式:从本......
  • JAVA基础-jdk8新特性
    Java8新特性:接口默认方法和静态方法JDK1.8打破了接口只提供了形式,而未提供任何具体实现这一限制,允许定义默认方法和静态方法。定义一个接口:packagecom.zgjt.design.defaults;importjava.util.function.Supplier;publicinterfaceAnimal{//接口默认方法,不必重......
  • Java开发的SRM供应商、在线询价、招投标采购一体化系统源码功能解析
    前言:随着全球化和信息化的发展,企业采购管理面临越来越多的挑战。传统的采购方式往往涉及到多个繁琐的步骤,包括供应商筛选、询价、招投标等,这些过程不仅耗时,而且容易出错。为了解决这些问题,供应商、询价、招投标一体化系统应运而生。该系统通过集成供应商管理、询价管理、招投标......
  • Java对象引用和内存管理的细节
    在Java中,当局部变量(比如方法参数)的作用域结束时,这个局部变量的引用确实不再存在,但这并不意味着它引用的对象会被销毁。对象的销毁是由Java的垃圾回收器(GarbageCollector,GC)来管理的。在Java中,局部变量(如方法参数)通常存储在栈内存(StackMemory)中,而对象实例(如ServletConfig对象)则......
  • 关于java代码Runtime.getRuntime().exec()执行shell脚本中的坑
    java操作shell脚本执行docker命令  Runtime.getRuntime().exec()是不能执行特殊符号如">"、"|"等必须通过"/bin/sh""-c"处理。另外java操作docker 不能分配  dockerexec-i(不要t).另外如果不确定脚本是否执行成功,可以通过waitFor返回的int结果,如果为0脚本执行......