Java 中的 IO 和 NIO

这篇具有很好参考价值的文章主要介绍了Java 中的 IO 和 NIO。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Java IO 介绍

Java IO(Input/Output)流是用于处理输入和输出数据的机制。它提供了一种标准化的方式来读取和写入数据,可以与文件、网络、标准输入输出等进行交互。

Java IO流主要分为两个流模型:字节流(Byte Stream)和字符流(Character Stream)。

字节流(Byte Stream)

  • InputStream:字节输入流的抽象基类,用于从源中读取字节数据。
  • OutputStream:字节输出流的抽象基类,用于向目标中写入字节数据。

常见的字节流实现类包括:

  • FileInputStream:从文件中读取字节数据。
  • FileOutputStream:将字节数据写入文件。
  • BufferedInputStream/BufferedOutputStream:带有缓冲区的字节流,提高读写效率。

字符流(Character Stream)

  • Reader:字符输入流的抽象基类,用于从源中读取字符数据。
  • Writer:字符输出流的抽象基类,用于向目标中写入字符数据。

常见的字符流实现类包括:

  • FileReader:从文件中读取字符数据。
  • FileWriter:向文件中写入字符数据。
  • BufferedReader/BufferedWriter:带有缓冲区的字符流,提高读写效率。

使用Java IO流的一般步骤如下:

  • 打开流:通过实例化相应的流对象,与输入或输出源建立连接。
  • 读取或写入数据:通过流对象提供的方法进行数据的读取或写入操作。
  • 关闭流:使用完流后,需要显式地关闭流,释放资源。

示例

// 需要注意的是,在使用流操作完成后,我们应该及时关闭流以释放资源,以上述代码为例,使用了try-with-resources语句来实现自动关闭流。
try (FileInputStream fis = new FileInputStream("input.txt");
     BufferedInputStream bis = new BufferedInputStream(fis);
     FileOutputStream fos = new FileOutputStream("output.txt");
     BufferedOutputStream bos = new BufferedOutputStream(fos)) {
    byte[] buffer = new byte[1024];
    int bytesRead;
    while ((bytesRead = bis.read(buffer)) != -1) {
        bos.write(buffer, 0, bytesRead);
    }
} catch (IOException e) {
    e.printStackTrace();
}

Java NIO(New IO)介绍

Java NIO(New IO)是Java 1.4版本引入的一套新的IO API,提供了更高效、更灵活的IO操作方式。

相比于传统的Java IO(InputStream/OutputStream),Java NIO主要有以下几个特点:

  • 通道(Channel)和缓冲区(Buffer):Java NIO使用通道来进行数据的读写,而不再依赖于流。通道可以双向传输数据,并且与底层操作系统交互的能力更强。数据通过缓冲区进行传输,可以提高IO操作的效率。
  • 非阻塞IO:Java NIO支持非阻塞IO操作,可以实现一个线程处理多个连接(例如网络连接),提高系统的并发性能。
  • 选择器(Selector):选择器是Java NIO提供的一种多路复用机制,可以用于监控多个通道的事件(如连接建立、数据到达等),从而实现高效的事件驱动编程模型。
  • 字符集编解码器:Java NIO提供了字符集编解码器,可以方便地进行字符集转换,支持Unicode、UTF-8等多种字符集。

使用Java NIO进行IO操作的一般步骤如下:

  • 打开通道(Channel):通过调用特定的通道类的open()方法打开一个通道。
  • 创建缓冲区(Buffer):创建适当大小的缓冲区,用于在通道和应用程序之间传输数据。
  • 读写数据:通过通道和缓冲区进行数据的读取和写入操作。
  • 关闭通道:使用完通道后,需要显式关闭通道以释放资源。

示例

try (RandomAccessFile file = new RandomAccessFile("file.txt", "rw");
    FileChannel channel = file.getChannel()) {
    ByteBuffer buffer = ByteBuffer.allocate(1024);
    int bytesRead = channel.read(buffer);
    while (bytesRead != -1) {
        buffer.flip();
        while (buffer.hasRemaining()) {
            System.out.print((char) buffer.get());
        }
        buffer.clear();
        bytesRead = channel.read(buffer);
    }
} catch (IOException e) {
    e.printStackTrace();
}

Java NIO提供了更高效、更灵活的IO处理方式,适用于需要处理大量连接或需要高性能和低延迟的场景。相比于传统的Java IO,它可以更好地满足现代应用对IO操作的需求。但需要注意的是,Java NIO的API较为复杂,使用时需要仔细理解和学习。

windows 安装 ffmpeg

choco install ffmpeg
choco install ffmpeg-full

完整示例

package java_io_nio;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class FileUtils {

    /**
     * 拷贝文件 FileInputStream、FileOutputStream、BufferedInputStream、BufferedOutputStream 应用
     * @param intputFilePath 输入文件
     * @param outputFilePath 输出文件
     */
    public static void copyFileByPath(String intputFilePath, String outputFilePath){
        try(FileInputStream fis = new FileInputStream(intputFilePath);
            BufferedInputStream bis = new BufferedInputStream(fis);
            FileOutputStream fos = new FileOutputStream(outputFilePath, false);
            BufferedOutputStream bos = new BufferedOutputStream(fos)){
          byte[] buffer = new byte[1024];
          int bytesRead;
          while ((bytesRead = bis.read(buffer)) != -1){
            bos.write(buffer, 0, bytesRead);
          }
        }catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    /**
     * 读取文件内容 BufferedReader 应用
     * @param filePath 文件路径
     * @return
     */
    public static String readFromFile(String filePath){
        StringBuffer result = new StringBuffer();
        try (FileInputStream fr = new FileInputStream(filePath);
            InputStreamReader isr = new InputStreamReader(fr, StandardCharsets.UTF_8);
            BufferedReader br = new BufferedReader(isr)) {
          String line;
          while((line = br.readLine()) != null){
            result.append(line);
          }
        } catch (IOException e) {
            e.printStackTrace();
        }

        return result.toString();
    }

    /**
     * 写入文件 BufferedWriter 应用
     * @param filePath 文件路径
     * @param content 文件内容
     */
    public static void writeToFile(String filePath, String content){
        try (FileOutputStream fos = new FileOutputStream(filePath);
            OutputStreamWriter osw = new OutputStreamWriter(fos, StandardCharsets.UTF_8);
            BufferedWriter bw = new BufferedWriter(osw)) {
          bw.write(content);
          bw.newLine();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 文件拷贝 NIO 应用
     * @param sourcePath 源文件
     * @param targetPath 目标文件
     */
    public static void transferFile(String sourcePath, String targetPath){
        Path sPath = Paths.get(sourcePath);
        Path tPath = Paths.get(targetPath);

        try {
            Files.copy(sPath, tPath, StandardCopyOption.REPLACE_EXISTING);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 视频格式转换 NIO 应用
     * @param inputPath 源格式
     * @param outputPath 目标格式
     */
    public static void videoFormatConversion(String inputPath, String outputPath){
        try {
            // 输入视频文件路径
            Path iPath = Paths.get(inputPath);

            // 输出转换后的视频文件路径
            Path oPath = Paths.get(outputPath);

            // 构建 FFmpeg 命令
            String ffmpegCommand = "ffmpeg -i " + iPath.toString() + " -c:v copy -c:a copy " + oPath.toString();

            // 执行 FFmpeg 命令
            Process process = Runtime.getRuntime().exec(ffmpegCommand);
            process.waitFor();

            // 检查转换后的文件是否存在
            if (Files.exists(oPath)) {
                System.out.println("视频格式转换成功!");
            } else {
                System.out.println("视频格式转换失败!");
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (IOException e){
            e.printStackTrace();
        }
    }

    /**
     * 读取数据 NIO 应用
     * @param socketChannel
     */
    private static void handleClientRequest(SocketChannel socketChannel) {
        try {
            ByteBuffer buffer = ByteBuffer.allocate(1024);
            int bytesRead = socketChannel.read(buffer);

            while (bytesRead != -1) {
                buffer.flip();

                while (buffer.hasRemaining()) {
                    System.out.print((char) buffer.get());
                }

                buffer.clear();
                bytesRead = socketChannel.read(buffer);
            }

            socketChannel.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {

        copyFileByPath("D:\\project\\uploadPath\\file_0.png", "D:\\project\\uploadPath\\file_1.png");

        String fileContent = readFromFile("D:\\project\\uploadPath\\test.txt");
        System.out.println("文件内容:" + fileContent);

        writeToFile("D:\\project\\uploadPath\\test.txt", "测试内容");

        transferFile("D:\\project\\uploadPath\\file_0.png", "D:\\project\\uploadPath\\file_2.png");

        videoFormatConversion("D:\\project\\uploadPath\\file_0.mp4", "D:\\project\\uploadPath\\file_0.mov");

        // NIO 网络编程
        try {
            // 创建 ServerSocketChannel
            ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
            serverSocketChannel.socket().bind(new InetSocketAddress(8080));
            serverSocketChannel.configureBlocking(false);

            System.out.println("服务器已启动,监听端口 8080...");

            // 创建线程池
            ExecutorService executorService = Executors.newFixedThreadPool(10);

            while (true) {
                // 监听客户端连接
                SocketChannel socketChannel = serverSocketChannel.accept();

                if (socketChannel != null) {
                    System.out.println("客户端连接成功!");

                    // 处理客户端请求的任务提交给线程池执行
                    executorService.submit(() -> handleClientRequest(socketChannel));
                }
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

参考文献

ffmpeg 下载文章来源地址https://www.toymoban.com/news/detail-695203.html

到了这里,关于Java 中的 IO 和 NIO的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Java NIO原理 (Selector、Channel、Buffer、零拷贝、IO多路复用)

    系列文章目录和关于我 最近有很多想学的,像netty的使用、原理源码,但是苦于自己对于操作系统和nio了解不多,有点无从下手,遂学习之。 上图粗略描述了网络io的过程,了解其中的拷贝过程有利于我们理解非阻塞io,以及IO多路复用的必要性。 数据从网卡到内核缓冲区 网

    2024年02月08日
    浏览(39)
  • java nio中的ByteBuffer扩展

    在jdk1.4之前对于输入输出只能使用InPutStream和outPutSream这类传统io模型,在jdk1.4之后新增了nio,什么是nio?nio是new input/output 的简称,nio的效率要比传统io效率高,主要原因就是nio利用了系统底层的零拷贝技术和多路复用技术。 NIO有三个核心概念 1、Channal通道 2、Buffer缓冲 3、Se

    2023年04月16日
    浏览(35)
  • java中的BIO NIO AIO

            多路复用IO模型是目前使用的比较多的模型。java中的NIO常用的理解是在 网络IO中,那么在网络IO中为什么NIO比BIO效率更高?我们的web项目中是用的哪种呢?可以往下看。         JavaNIO实际上就是多路复用IO。在多路复用IO模型中,会有一个线程不断地区轮询多个

    2024年02月15日
    浏览(40)
  • Java中的BIO、NIO与AIO

       I/O 模型简单的理解:就是用什么样的通道进行数据的发送和接收,很大程度上决定了程序通信的性能。 Java 共支持 3 种网络编程模型 I/O 模式: BIO 、 NIO 、 AIO 。    Java BIO(Blocking I/O) :是传统的java io 编程,其相关的类和接口在 java.io。同步并阻塞(传统阻塞型),服

    2024年04月26日
    浏览(31)
  • 代码分析Java中的BIO与NIO

    OS:Win10(需要开启telnet服务,或使用第三方远程工具) Java版本:8 BIO(Block IO),即同步阻塞IO,特点为当客户端发起请求后,在服务端未处理完该请求之前,客户端将一直等待服务端的响应。而服务端在此时也专注于该请求的处理,无法处理其它客户端的请求。 在IDEA运行上述

    2024年02月14日
    浏览(38)
  • Java中的三种I/O模型:BIO、NIO和AIO

    I/O(输入/输出)操作是任何应用程序中必不可少的一部分,它涉及到与文件、网络或其他设备之间的数据传输。Java提供了几种不同的I/O模型,其中最常见的是AIO(异步非阻塞I/O)、BIO(阻塞I/O)和NIO(非阻塞I/O)。这些模型在处理I/O操作时具有不同的工作方式、特性和适用

    2024年02月08日
    浏览(38)
  • Java NIO (三)NIO Channel类

            前面提到,Java NIO中一个socket连接使用一个Channel来表示。从更广泛的层面来说,一个通道可以表示一个底层的文件描述符,例如硬件设备、文件、网络连接等。然而,远不止如此,Java NIO的通道可以更加细化。例如,不同的网络传输协议,在Java中都有不同的NIO Chann

    2024年01月18日
    浏览(47)
  • IO、NIO、IO多路复用

    IO是什么? 网络IO是如何连接的? 下面是一次网络读取内容的I/O示意图,数据先从外设(网卡)到内核空间,再到用户空间(JVM),最后到应用程序的一个过程。 上述一次I/O读取,所谓的阻塞和非阻塞体现在哪里呢? Java最早期的版本的I/O就是这样实现的。当程序调用到读取

    2024年01月20日
    浏览(42)
  • JAVA NIO简解

    Java nio是Java的一个新的输入输出(NewInput/Output)API,它提供了一些高效的数据处理方式,如缓冲区(buffers)、字符集(charsets)、通道(channels)和选择器(selectors)。 Java NIO可以实现非阻塞式的多路复用输入输出,提高了程序的性能和可扩展性。Java nio是在Java 1.4版本中引入

    2023年04月16日
    浏览(36)
  • Java NIO

    在传统的 Java I/O 模型(BIO)中,I/O 操作是以阻塞的方式进行的。也就是说, 当一个线程执行一个 I/O 操作时,它会被阻塞直到操作完成 。这种阻塞模型在处理多个并发连接时可能会导致性能瓶颈,因为需要为每个连接创建一个线程,而线程的创建和切换都是有开销的。 为了

    2024年01月25日
    浏览(39)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包