龙空技术网

Java I/O 流的秘密:你想要了解吗?

你的老师父 194

前言:

此刻咱们对“java流的关闭”大致比较关注,小伙伴们都需要学习一些“java流的关闭”的相关内容。那么小编也在网络上网罗了一些有关“java流的关闭””的相关资讯,希望朋友们能喜欢,你们快快来学习一下吧!

Java IO 流是 Java 编程中不可或缺的一部分。它提供了许多类和方法来读写数据,包括文件、网络连接、内存缓冲区等等。在这篇博客中,我将详细介绍 Java IO 流的所有知识点,包括字节流和字符流的概念Java IO(输入/输出)流是Java IO流是Java编程中重要的一部分,它用于处理各种输入输出操作。在这篇博客中,我们将对Java IO流进行全面的讲解,包括IOJava IOJava I/O(即Java Input/Output)是Java语言中处理输入和输出数据的一种机制,是与底层操作系统独立的一种输入/输出操作方式。本文将全面介绍 Java I/O 流相关知识点,包括基础概念、I/O 流类型、I/O 流的应用场景、缓冲区、NIO、常见应用等。

一、Java I/O流基础概念

在开始深入了解 Java I/O 流前,我们需要先掌握以下基础概念:

1. 数据流

Java I/O 流是数据的抽象,表示数据在程序之间传输的路径。数据可以是文件、网络连接、进程等。

2. 字节流和字符流

数据按照单位分为字节流和字符流两种类型。字节流以字节(8位)为单位传输数据,而字符流以字符(16位)为单位传输数据。通常我们使用字符流来处理文本文件,使用字节流来处理二进制文件或者网络数据。

3. 输入流和输出流

输入流和输出流是相对于程序来说的。输入流用于从数据源读取数据到程序中,而输出流则将程序中的数据写出到目标位置。

二、Java I/O流类型

Java I/O 流分为四个抽象类,它们是:

1. InputStream 和 OutputStream

InputStream 是所有输入流的抽象基类,而 OutputStream 是所有输出流的抽象基类。

2. Reader 和 Writer

Reader 是所有输入字符流的抽象基类,而 Writer 是所有输出字符流的抽象基类。

使用 I/O 流时还需要注意以下几点:

I/O 流要及时关闭,否则可能导致资源泄露。I/O 操作是一个比较耗时的过程,如果不必要,应该尽量避免频繁进行 I/O 操作。为了提高 I/O 的效率,可以使用缓冲区。三、Java I/O流的应用场景

Java I/O 流可以用于多种场合,包括读写文件、网络通信、进程间通信等。

1. 读写文件

在 Java 中,我们可以使用 FileInputStream 和 FileOutputStream 类来读写文件。这两个类都是字节流类型,可用于读写二进制文件和文本文件。

try (FileInputStream input = new FileInputStream("file.txt")) { byte[] buffer = new byte[1024]; int length; while ((length = input.read(buffer)) != -1) { System.out.write(buffer, 0, length); }} catch (IOException e) { e.printStackTrace();}

上面的代码使用 FileInputStream 类从 "file.txt" 文件中读取数据,并打印出来。

对于文本文件,我们也可以使用 FileReader 和 FileWriter 类来读写文件。这两个类都是字符流类型。

try (FileReader reader = new FileReader("file.txt")) { char[] buffer = new char[1024]; int length; while ((length = reader.read(buffer)) != -1) { System.out.print(new String(buffer, 0, length)); }} catch (IOException e) { e.printStackTrace();}

这个代码使用 FileReader 类从 "file.txt" 文件中读取数据,并打印出来。

2. 网络通信

Java I/O 流也可以用于网络通信。我们可以使用 Socket 和 ServerSocket 类来创建客户端和服务器端,从而实现网络通信。

try (Socket socket = new Socket("127.0.0.1", 8080)) { OutputStream output = socket.getOutputStream(); output.write("Hello World".getBytes()); output.flush(); InputStream input = socket.getInputStream(); byte[] buffer = new byte[1024]; int length = input.read(buffer); System.out.println(new String(buffer, 0, length));} catch (IOException e) { e.printStackTrace();}

上面的代码使用 Socket 类向 "127.0.0.1" 的 8080 端口发送数据,并等待服务器返回响应。

try (ServerSocket serverSocket = new ServerSocket(8080)) { while (true) { Socket socket = serverSocket.accept(); InputStream input = socket.getInputStream(); byte[] buffer = new byte[1024]; int length = input.read(buffer); System.out.println(new String(buffer, 0, length)); OutputStream output = socket.getOutputStream(); output.write("Hello Client".getBytes()); output.flush(); socket.close(); }} catch (IOException e) { e.printStackTrace();}

上面的代码使用 ServerSocket 类监听 8080 端口,等待客户端连接。一旦有连接请求,就接收并处理它,并向客户端返回响应数据。

3. 进程间通信

Java I/O 流还可以用于进程间通信。我们可以使用 PipedInputStream 和 PipedOutputStream 类来实现这个功能。

try { PipedInputStream inputStream = new PipedInputStream(); PipedOutputStream outputStream = new PipedOutputStream(inputStream); Thread thread1 = new Thread(() -> { try { outputStream.write("Hello World".getBytes()); outputStream.flush(); outputStream.close(); } catch (IOException e) { e.printStackTrace(); } }); Thread thread2 = new Thread(() -> { try { byte[] buffer = new byte[1024]; int length = inputStream.read(buffer); System.out.println(new String(buffer, 0, length)); inputStream.close(); } catch (IOException e) { e.printStackTrace(); } }); thread1.start(); thread2.start(); thread1.join(); thread2.join();} catch (IOException | InterruptedException e) { e.printStackTrace();}

上面的代码创建了一个 PipedInputStream 和一个 PipedOutputStream 对象,并将它们连接起来。然后,我们在两个线程中分别读写数据。

四、缓冲区

Java I/O 流也支持缓冲区操作。缓冲区是一块内存空间,用于暂存数据。使用缓冲区可以提高 I/O 的效率,减少频繁读写的次数。

1. 字节缓冲区

Java I/O 中提供了 BufferedInputStream 和 BufferedOutputStream 类,可以通过它们来实现字节缓冲区操作。

try (BufferedInputStream input = new BufferedInputStream(new FileInputStream("file.txt")); BufferedOutputStream output = new BufferedOutputStream(new FileOutputStream("file_copy.txt"))) { byte[] buffer = new byte[1024]; int length; while ((length = input.read(buffer)) != -1) { output.write(buffer, 0, length); }} catch (IOException e) { e.printStackTrace();}

上面的代码使用 BufferedInputStream 和 BufferedOutputStream 类从 "file.txt" 文件中读取数据,并写入到 "file_copy.txt" 文件中。

2. 字符缓冲区

Java I/O 中提供了 BufferedReader 和 BufferedWriter 类,可以通过它们来实现字符缓冲区操作。

try (BufferedReader reader = new BufferedReader(new FileReader("file.txt")); BufferedWriter writer = new BufferedWriter(new FileWriter("file_copy.txt"))) { String line; while ((line = reader.readLine()) != null) { writer.write(line); writer.newLine(); }} catch (IOException e) { e.printStackTrace();}

上面的代码使用 BufferedReader 和 BufferedWriter 类从 "file.txt" 文件中读取数据,并写入到 "file_copy.txt" 文件中。

五、NIO

Java NIO(New I/O)是为了解决 Java I/O 中存在的一些问题而出现的。Java NIO 主要提供了以下几个类:

1. Buffer

Buffer 是一个对象,它包含一些被写入或者将要被读出的数据。在 NIO 中,数据是从通道(Channel)读取到缓冲区中,也是从缓冲区写入到通道中的。

ByteBuffer buffer = ByteBuffer.allocate(1024);int bytesRead = channel.read(buffer);

上面的代码使用 ByteBuffer 类从通道中读取数据,并存储到缓冲区中。

2. Channel

Channel 是 NIO 中一个比较重要的概念。它类似于 Java I/O 中的流,但又有一些不同之处。与流不同的是,通道是双向的,数据可以从通道读取,也可以写入到通道中。

try (FileChannel channel = FileChannel.open(Paths.get("file.txt"))) { 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();}

上面的代码使用 FileChannel 类### 2. Channel

Channel 是一个对象,它可以用于读取和写入数据。在 NIO 中,所有的 I/O 操作都是通过 Channel 来进行的。

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

上面的代码使用 FileChannel 类从 "file.txt" 文件中读取数据,并打印出来。3. Selector

Selector 是一个对象,它可以用来检查一个或多个 NIO 通道,并确定哪些通道已经准备好进行读写操作。这样就可以在不阻塞线程的情况下处理多个通道。

Selector selector = Selector.open();channel.configureBlocking(false);SelectionKey key = channel.register(selector, SelectionKey.OP_READ);while (true) { int readyChannels = selector.select(); if (readyChannels == 0) { continue; } Set<SelectionKey> selectedKeys = selector.selectedKeys(); Iterator<SelectionKey> keyIterator = selectedKeys.iterator(); while (keyIterator.hasNext()) { SelectionKey key = keyIterator.next(); if (key.isReadable()) { // 处理可读事件 } else if (key.isWritable()) { // 处理可写事件 } keyIterator.remove(); }}

上面的代码使用 Selector 类来监控通道的状态,并处理相应的事件。

六、常见应用

Java I/O 流被广泛应用于各个领域,以下是一些常见的应用场景:

1. 文件上传和下载

Java I/O 流可以用于实现文件上传和下载功能。客户端发送数据到服务器时,使用 OutputStream 类将数据写入到 Socket 中,服务器接收数据时使用 InputStream 类从 Socket 中读取数据。

2. 数据库操作

Java I/O 流也可以用于数据库操作。通过使用 InputStream 和 OutputStream 类,可以将数据从数据库中读取出来或者写入到数据库中。

3. 网络爬虫

网络爬虫需要从网页中抽取信息,而这些信息通常以文本形式存在。因此,Java I/O 流可以用于从网页中读取数据,并对数据进行分析和处理。

4. 图像处理

Java I/O 流还可以用于图像处理。我们可以使用 BufferedImage 类从图片文件中读取图像数据,并使用 ImageIO 类将图像数据写入到新的图片文件中。

结语

本文介绍了 Java I/O 流相关知识点,包括基础概念、I/O 流类型、I/O 流的应用场景、缓冲区、NIO、常见应用等。掌握了这些知识点,我们就可以更加灵活地使用 Java I/O 流,并在实际开发中提高效率。

标签: #java流的关闭