Java I/O 和 oKio

栏目: Java · 发布时间: 5年前

内容简介:从文件读数据到内存里面,方便操作网络数据和本地文件,操作更加灵活了,所有的操作都是利用String来代替就是 24_io.txt 如果没有 就会帮忙创建,如果有就不会创建,这个就是用java io做的一个基本操作不是直接操作文件,而是直接操作流,通过一根管子,插到这个文件上,然后对这个流进行操作,这样可以对不同的外部对象使用统一的操作形式,不管是往一个文件还是网络还是其他形式,我都是创造一个String的格式,然后往这个String 去写 或者 去存 然后去读 这个String,相当于在程序内部和外界之间搭

学习目标

  • java传统io如何使用
  • 非阻塞 nio 是怎么回事
  • okio 的优势与使用

java传统io: 流

从文件读数据到内存里面,方便操作网络数据和本地文件,操作更加灵活了,所有的操作都是利用String来代替

熟悉java io 的基本操作

就是 24_io.txt 如果没有 就会帮忙创建,如果有就不会创建,这个就是用java io做的一个基本操作

Java I/O 和 oKio
try {
// 输出流的管子
           final FileOutputStream fileOutputStream = new FileOutputStream("./24_io/24_io.txt");
           fileOutputStream.write('a');
           fileOutputStream.write('b');

       } catch (FileNotFoundException e) {
           e.printStackTrace();
       } catch (IOException e) {
           e.printStackTrace();
       }
复制代码

不是直接操作文件,而是直接操作流,通过一根管子,插到这个文件上,然后对这个流进行操作,这样可以对不同的外部对象使用统一的操作形式,不管是往一个文件还是网络还是其他形式,我都是创造一个String的格式,然后往这个String 去写 或者 去存 然后去读 这个String,相当于在程序内部和外界之间搭建了一个桥梁 ,我虽然把处理单件事件变复杂了,比如:我一辈子都处理文件,或者一辈子处理网络 ,把这个变复杂了,但是整体上有一个一致性,所以扩展性变更好了,由于这个扩展性,他做的事情也变多了,不止是可以读写文件,还可以和网络交互,而且还有其他形式可以和网络操作,也可以通过其他扩展的String来操作

java 文件的 读取操作

资源的持有会消耗内存,所以我们在不需要这些资源的时候我们需要释放这些资源,所谓的释放就是把文件关闭,把文件的关闭本质就是把流给舍弃调,java 7 以下我们需要在 finally处理如下:

InputStream sFileInputStream = null;
        try {
            sFileInputStream = new FileInputStream("./24_io/24_io.txt");
            System.out.println((char) sFileInputStream.read());
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (sFileInputStream != null) {
                try {
                    sFileInputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

        }
复制代码

java 7 以及以上 在 try () 处理即可,自动关流

try (InputStream sFileInputStream = new FileInputStream("./24_io/24_io.txt")) {
            System.out.println((char) sFileInputStream.read());
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
复制代码

所有的流都实现了 Closeable,所有的 Closeable 如果在try 里面做初始化 都会被自动关闭

public abstract class InputStream implements Closeable {}
复制代码

怎么和文件进行互操作,怎么把文件转换成字符?

try (InputStream sFileInputStream = new FileInputStream("./24_io/24_io.txt")) {
            Reader inputStreamReader = new InputStreamReader(sFileInputStream);
            final BufferedReader bufferedInputStream = new BufferedReader(inputStreamReader);
            System.out.println(bufferedInputStream.readLine());
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
复制代码

readLine的本身的意义不是一行读,他会额外读一些内容到自己内部,它本身的意思是增加缓冲,他会额外读一些内容到缓冲

Java I/O 和 oKio

从BufferReader 源码可以看出:

private static int defaultCharbufferSize = 8192
复制代码

默认可以读 8192 个字节,为了提高性能,我们必须设置一个默认值

Buffer 写数据 其实是在缓冲里面放数据,所以写完之后记得及时 flush 将目标东西刷新到目标区

try (OutputStream sFileInputStream = new FileOutputStream("./24_io/24_io.txt")) {

            final BufferedOutputStream inputStream = new BufferedOutputStream(sFileInputStream);
            inputStream.write('a');
            inputStream.write('b');
            inputStream.write('M');
            inputStream.flush();
        } catch (Exception e) {
            e.printStackTrace();
        }
复制代码

如: outPutStream 没有 flush 不会写成功的,那么为什么Buffer不能自动刷新呢?

因为缓冲是为了做效率, 和文件操作性能会比较低,所以尽量减少这样的操作,把频率降低,把多次io给合起来,这样才能提高性能呢.Buffer 会导致输出不同步这是必然的事情

同样在 try 里面 做数据包装操作,也会自动刷新缓存到目标区

try (OutputStream sFileInputStream = new FileOutputStream("./24_io/24_io.txt"); final BufferedOutputStream inputStream = new BufferedOutputStream(sFileInputStream)) {
            inputStream.write('a');
            inputStream.write('b');
            inputStream.write('M');
         } catch (Exception e) {
            e.printStackTrace();
        }
复制代码

文件复制

java没有文件复制的功能的,那么怎么做文件复制呢,我们要做的是把文件数据一个一个搬

try (InputStream fileInputStream = new FileInputStream("./24_io/24_io.txt");
             OutputStream outputstream = new FileOutputStream("./24_io/text_copy.txt")) {

            final byte[] bytes = new byte[1024];
            int read = 0;
            while ((read = fileInputStream.read(bytes)) != -1) {
                outputstream.write(bytes, 0, read);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
复制代码

如果想提高性能 我们可以加 Buffer

这就是 Java 的 I/O 原理,核心就是:内存与外界的交互,你可以用 inputStream 和 outPutStream 做对接

Socket 和 ServerSocket 之间的网络交互

和文件交互是 java i/o 里面 和 网络进行交互的,就像和文件交互 用 File 比如: 我做个服务器

try {
            final ServerSocket serverSocket = new ServerSocket(8080);
            final Socket socket = serverSocket.accept();
            final BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            final BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
            while (true) {
                final String data = reader.readLine();
                writer.write("你给我输入了: " + data);
                writer.flush();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
复制代码

nio 与传统 io的区别

  • 传统io用的是插管道的方式 

  • nio 的 Channel 是双向的,传统io是单向的

try {
            final RandomAccessFile file = new RandomAccessFile("./24_io/24_io.txt", "r");
            final FileChannel channel = file.getChannel();
            final ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
            channel.read(byteBuffer);
            byteBuffer.flip();
            System.out.println(Charset.defaultCharset().decode(byteBuffer));
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
复制代码
  • nio 也用到了缓冲 buffer nio 可以被操作的,nio的Buffer是强制使用的,不好用
try {
            final ServerSocketChannel channel = ServerSocketChannel.open();
            channel.bind(new InetSocketAddress(8080));
            final SocketChannel socketChannel = channel.accept();
            final ByteBuffer byteBuffer = ByteBuffer.allocate(1024);

            while (socketChannel.read(byteBuffer) != -1) {
                byteBuffer.flip();
                socketChannel.write(byteBuffer);
                byteBuffer.clear();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
复制代码
  • nio 有非阻塞的支持,只能网络才能使用
try {
            final ServerSocketChannel channel = ServerSocketChannel.open();
            channel.bind(new InetSocketAddress(8080));
            channel.configureBlocking(false);
            final SocketChannel socketChannel = channel.accept();
            final ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
            while (socketChannel.read(byteBuffer) != -1) {
                byteBuffer.flip();
                socketChannel.write(byteBuffer);
                byteBuffer.clear();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
复制代码

为什么 非阻塞式 nio 设置 configureBlocking 开关 会报NullException?

Exception in thread "main" java.lang.NullPointerException
复制代码

因为 channel.accept() 没有拿到数据,socketChannel 为 null,还没有发起请求就设置 false了

okio

okio 作为一个外部对象作为输入输出,okio是独立形式存在的.

try (BufferedSource  source = Okio.buffer(Okio.source(new File("./24_io/24_io.txt")) )) {
            final Buffer buffer = new Buffer();
            source.read(buffer, 1024);
            System.out.println(buffer.readUtf8());

        } catch (Exception e) {
            e.printStackTrace();
        }
复制代码

okio 和 传统 io 作交互

final Buffer buffer = new Buffer();
        try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(buffer.outputStream()));
             BufferedReader bufferReader = new BufferedReader(new InputStreamReader(buffer.inputStream()))) {
            writer.write("哈哈哈哈");
            writer.flush();
            System.out.println("read: " + bufferReader.readLine());
        } catch (IOException e) {
            e.printStackTrace();
        }
复制代码

以上所述就是小编给大家介绍的《Java I/O 和 oKio》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Responsive Web Design

Responsive Web Design

Ethan Marcotte / Happy Cog / 2011-6 / USD 18.00

From mobile browsers to netbooks and tablets, users are visiting your sites from an increasing array of devices and browsers. Are your designs ready? Learn how to think beyond the desktop and craft be......一起来看看 《Responsive Web Design》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具