Java IO和Okio

扔物线学习笔记总结

  • 传统I/O
  • NIO
  • Okio

io 通过流,不是直接读

失去方便性,扩展灵活

  • 基本操作小例子,往文件里面输出数据的示例,不直接操作文件,通过“管子”操作

public class Main {
    public static void main(String[] args) {
        File file = new File("./a.txt");
        try {
            FileOutputStream fileOutputStream = new FileOutputStream(file);
            fileOutputStream.write('a');
            fileOutputStream.write('b');
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

FileOutputStream 读写二进制,字符串需要使用Reader,Writer

读写“插管子后”需要关闭,因为读写信息占用内存资源(例如读到哪个字节),需要释放,所以要及时关闭

成功失败都要关闭,传统方式在finally关闭 把变量在外面初始化

Java7开始,放在try后面括号里完成之后自动关闭,原因实现了 Closeable

字符流

相当于把管子插到字节流上

小结

Reader 是字符流

Buffer 是缓存,然后一起与文件交互

文件复制

Android Java FileUtils Kotlin copyto

的表皮下真正的代码

 /**
     * 文件复制
     */
    private static void io5() {

        try (
                InputStream inputStream = new FileInputStream("./a.txt");
                OutputStream outputStream = new FileOutputStream("./b.txt")
        ) {
            byte[] bytes = new byte[1024];
            int read;
            while ((read = inputStream.read(bytes)) != -1) {
                outputStream.write(bytes, 0, read);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

IO 就是内存和外界的交互

常用的File 类

网络交互Socket IO,

做TCP链接,网站针对字符

客户端

 public static void io6() {
        try (
                Socket socket = new Socket("rengwuxian.com", 80);
                BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()))
        ) {
            writer.write("GET / HTTP/1.1\n" + "Host:www.example.com\n\n");
            //发送到网站
            writer.flush();
            //看返回结果
            String message;
            while ((message = reader.readLine())!=null){
                System.out.println(message);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

小结代码

package test.io;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

public class Main {
    public static void main(String[] args) {
//        io1();
//        io2();
//        io3();
//        io4();
//        io5();
//        io6();
        io7();
    }

    /**
     * 写文件
     */
    private static void io1() {
        File file = new File("./a.txt");
        try (OutputStream fileOutputStream = new FileOutputStream(file);) {
            fileOutputStream.write('a');
            fileOutputStream.write('b');
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 读文件
     */
    private static void io2() {
        File file = new File("./a.txt");
        try (InputStream fileInputStream = new FileInputStream(file)) {
            //读的都是字节
            System.out.println((char) fileInputStream.read());
            System.out.println((char) fileInputStream.read());
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    /**
     * 读文件buffer
     */
    private static void io3() {
        File file = new File("./a.txt");
        try (InputStream fileInputStream = new FileInputStream(file);
             //读的都是字节
             //第二层字节上字符,也可以使用FileReader一步到位 字符流
             Reader reader = new InputStreamReader(fileInputStream);
             //第三层 整行读 再套一层 buffer 增加buffer,一次多读一些defaultCharBufferSize 8*1024
             BufferedReader bufferedReader = new BufferedReader(reader)
        ) {
            System.out.println(bufferedReader.readLine());
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 写文件 buffer 缓冲需要flush
     * 文件与内存交互性能低,所以buffer输出不同步
     * close会自动flush
     */
    private static void io4() {
        File file = new File("./a.txt");
        try (OutputStream fileOutputStream = new FileOutputStream(file);
             OutputStream outputStream = new BufferedOutputStream(fileOutputStream);
        ) {
            outputStream.write('a');
            outputStream.write('p');
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 文件复制
     */
    private static void io5() {

        try (
                InputStream inputStream = new FileInputStream("./a.txt");
                OutputStream outputStream = new FileOutputStream("./b.txt")
        ) {
            byte[] bytes = new byte[1024];
            int read;
            while ((read = inputStream.read(bytes)) != -1) {
                outputStream.write(bytes, 0, read);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * socket客户端
     */
    public static void io6() {
        try (
                Socket socket = new Socket("rengwuxian.com", 80);
                BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()))
        ) {
            writer.write("GET / HTTP/1.1\n" + "Host:www.example.com\n\n");
            //发送到网站
            writer.flush();
            //看返回结果
            String message;
            while ((message = reader.readLine()) != null) {
                System.out.println(message);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * Socket 服务端
     */
    public static void io7() {
        try (
                ServerSocket socketServer = new ServerSocket(80);
                //阻塞等待访问,就一次哦
                Socket socket = socketServer.accept();
                BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()))
        ) {
            //先读后写根据读取内容写入,这里直接写入
            writer.write("HTTP/1.1 200 OK\n" +
                    "Server: nginx/1.14.0 (Ubuntu)\n" +
                    "Date: Sun, 20 Jun 2021 09:17:34 GMT\n" +
                    "Content-Type: text/html\n" +
                    "Content-Length: 612\n" +
                    "Last-Modified: Fri, 11 Oct 2019 04:19:03 GMT\n" +
                    "Connection: keep-alive\n" +
                    "ETag: \"5da002b7-264\"\n" +
                    "Accept-Ranges: bytes\n" +
                    "\n" +
                    "\n" +
                    "\n" +
                    "\n" +
                    "Welcome to nginx!\n" +
                    "\n" +
                    "\n" +
                    "\n" +
                    "

Test

\n" + "

If you see this page, the nginx web server is successfully installed and\n" + "working. Further configuration is required.

\n" + "\n" + "

For online documentation and support please refer to\n" + "nginx.org.
\n" + "Commercial support is available at\n" + "nginx.com.

\n" + "\n" + "

Thank you for using nginx.

\n" + "\n" + "\n" + "\n" + "Process finished with exit code 0\n\n"); //发送到网站 writer.flush(); } catch (IOException e) { e.printStackTrace(); } } }

NIO

  • 传统I/O:Stream ;NIO:Channel(双向)
  • NIO的Buffer
    • Buffer可以被操作;强制使用Buffer;Buffer不好用
  • 非阻塞式
    • 只是【支持非阻塞式】,默认式阻塞式
    • 只有网络交互支持非阻塞,文件交互不支持
 /**
     * NIO基本阻塞式读取
     */
    public static void io8(){
        //获取Channel
        try {
            RandomAccessFile file = new RandomAccessFile("./a.txt","r");
            FileChannel channel =file.getChannel();
            ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
            channel.read(byteBuffer);
            //不能直接从ByteBuffer中读
            // capacity 容量 position 位置 limit 限制
//            byteBuffer.limit(byteBuffer.position());
//            byteBuffer.position(0);
            //   byteBuffer.flip(); =   byteBuffer.limit(byteBuffer.position());+   byteBuffer.position(0);
            byteBuffer.flip();
            System.out.println(Charset.defaultCharset().decode(byteBuffer));
            //读取完要归位
            byteBuffer.clear();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

非阻塞

    public static void io9() {
        try {
            ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
            serverSocketChannel.bind(new InetSocketAddress(80));
            //设置使用非阻塞式
            serverSocketChannel.configureBlocking(false);
            Selector selector = Selector.open();
            //注册监听
            serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
            while (true) {
                selector.select();//阻塞了,不过所有Channel都可以往这里注册
                for (SelectionKey key : selector.selectedKeys()){
                    if (key.isAcceptable()){
                        SocketChannel socketChannel = serverSocketChannel.accept();
                        ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
                        while ( socketChannel.read(byteBuffer)!=-1){
                            byteBuffer.flip();
                            socketChannel.write(byteBuffer);
                            //读取完要归位
                            byteBuffer.clear();
                        }
                    }
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

Okio

  • 也是基于插管,单向 Source和Sink
  • 支持Buffer
    • 可以对Buffer进行操作
    • Buffer很好用
    • 不强制使用Buffer

用法

需要先导入依赖

implementation 'com.squareup.okio:okio:2.4.3'

    public static void io10() {
        File file = new File("./a.txt");
//        try (Source source=Okio.source(file);){
//            Buffer buffer = new Buffer();
//            //Buffer 是个工具 ,read是往buffer里写
//            //source ->buffer ->read
//            source.read(buffer,1024);
//            System.out.println(buffer.readUtf8Line());
//            //不带buffer 不能整行读
//
//        }
        try (BufferedSource source = Okio.buffer(Okio.source(file))) {
            System.out.println(source.readUtf8Line());
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    public static void io11() {
        File src = new File("./a.txt");
        File dest = new File("./c.txt");
        try (  BufferedSource bufferedSource = Okio.buffer(Okio.source(src));
               BufferedSink bufferedSink = Okio.buffer(Okio.sink(dest));
        ){
            bufferedSink.writeAll(bufferedSource);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

你可能感兴趣的:(Java IO和Okio)