Java I/O(Input/Output)是 Java 编程语言中用于读写数据的 API。它的主要组成部分是 java.io 包,其中包含了用于处理输入/输出的流、文件、缓冲区和其他对象。
Java NIO(New Input/Output)是 Java 编程语言中的一个新的 I/O API,它是 Java 1.4 中引入的。它的主要组成部分是 java.nio 包,其中包含了用于处理输入/输出的通道、缓冲区和其他对象。
Java NIO 有几个主要优势:
面向缓冲区:Java NIO 使用缓冲区来进行读写操作,这意味着它可以在一次读写操作中处理多个字节。这与 Java IO 的流式读写方式不同,可以提高效率。
非阻塞 I/O:Java NIO 支持非阻塞 I/O,这意味着线程可以在等待输入/输出操作完成时做其他事情。这与 Java IO 中的阻塞 I/O 不同,可以提高程序的响应能力。
通道:Java NIO 使用通道来读写数据,这意味着可以通过单个通道进行输入和输出操作。这与 Java IO 中的输入流和输出流不同,可以提高效率。
总的来说,Java NIO 是一个比 Java IO 更快速、高效的 I/O API。它通常用于需要处理大量数据的应用程序,如服务器和网络应用程序。
Java NIO 的另一个优势是它提供了更为灵活的文件系统访问方式。它提供了一个新的 API,可以通过文件系统中的路径来访问文件和目录,并可以对文件和目录执行操作。这个 API 在 java.nio.file 包中,是 Java 7 中引入的。
总的来说,Java NIO 是一个功能强大的 I/O API,可以帮助您更快速、高效地处理数据。它提供了面向缓冲区、非阻塞和通道的 I/O 方式,以及用于访问文件系统的灵活 API。
java.nio.file 包是 Java 7 中引入的新包,提供了在文件系统中进行文件 I/O 操作的强大工具。它建立在 java.nio 包的基础之上,提供了一些高级功能,如文件遍历、监视文件系统变化、链接检测和文件属性访问等。
其中一些常用的类和接口包括:
Path:表示文件系统中的路径。
Files:提供了各种操作文件和目录的工具方法。
FileSystem:表示文件系统。
FileSystems:用于访问文件系统的工厂。
FileStore:表示文件系统中的存储。
FileAttribute:用于读取和设置文件属性的工具接口。
使用 java.nio.file 包时,最常见的操作是使用 Path 对象来描述文件的位置,然后使用 Files 类的工具方法来执行操作。例如,要创建一个新文件,可以使用以下代码:
import java.nio.file.*;
Path file = Paths.get("/tmp/test.txt");
Files.createFile(file);
要读取文件内容,可以使用 Files.readAllLines 方法:
import java.nio.file.*;
import java.util.List;
Path file = Paths.get("/tmp/test.txt");
List<String> lines = Files.readAllLines(file);
for (String line : lines) {
System.out.println(line);
}
java.nio.file 包是在 Java 7 中引入的,并不是特定于 Android 的包。它是 Java 平台标准版(JSE)的一部分,并且可以在所有支持 Java 7 的平台上使用。
在 Android 上,您可以在 Android 5.0(API 级别 21)及更高版本中使用 java.nio.file 包。有关 Android 中可用的 Java 版本的更多信息,请参阅 Android 开发人员文档中的“支持的 Java 版本”页面:
https://developer.android.com/studio/write/java8-support#supported-java-versions
请注意,由于 Android 是基于 Java 的,因此您可以在 Android 上使用所有 Java 标准库中的类和接口。但是,某些类和接口可能受到 Android 特定的限制,例如可能无法在 Android 上使用某些与系统底层交互的功能。
如果您想在 Java 中拷贝文件,可以使用 java.nio.file 包中的 Files 类的 copy 方法。例如,要拷贝文件 /tmp/source.txt 到目录 /tmp/destination 中,可以使用以下代码:
import java.nio.file.*;
public class CopyFile {
public static void main(String[] args) throws Exception {
Path source = Paths.get("/tmp/source.txt");
Path destination = Paths.get("/tmp/destination/copy.txt");
Files.copy(source, destination, StandardCopyOption.REPLACE_EXISTING);
}
}
在这里,StandardCopyOption.REPLACE_EXISTING 表示如果目标文件已存在,则替换它。
如果您想进行更复杂的操作,可以使用 java.io 包中的 FileInputStream 和 FileOutputStream。例如,要拷贝文件 /tmp/source.txt 到目录 /tmp/destination 中,可以使用以下代码:
import java.io.*;
public class CopyFile {
public static void main(String[] args) throws Exception {
FileInputStream in = new FileInputStream("/tmp/source.txt");
FileOutputStream out = new FileOutputStream("/tmp/destination/copy.txt");
byte[] buffer = new byte[1024];
int length;
while ((length = in.read(buffer)) > 0) {
out.write(buffer, 0, length);
}
in.close();
out.close();
}
}
请注意,使用 FileInputStream 和 FileOutputStream 时,需要手动管理缓冲区和输入/输出流。
面向缓冲区的 I/O 指的是使用缓冲区来读写数据的方式。
在面向缓冲区的 I/O 中,数据读写操作都是从内存中的缓冲区进行的。当要从文件或网络套接字中读取数据时,会先将数据读入缓冲区,然后从缓冲区中读取数据。当要写入文件或网络套接字时,也是先将数据写入缓冲区,然后再将缓冲区的数据写入文件或网络套接字。
这种方式的优势在于,可以一次性处理多个字节,而不是像流式 I/O 一样一次只能处理一个字节。这样可以提高效率,因为减少了系统调用次数;
面向缓冲区的 I/O 的另一个优势在于,可以避免大量的系统调用。在流式 I/O 中,每次读写操作都会导致一次系统调用,这样可能会导致性能下降。而在面向缓冲区的 I/O 中,可以一次性读写多个字节,减少系统调用的次数,从而提高性能。
另外,在面向缓冲区的 I/O 中,还可以使用缓冲区的相关方法,如 flip、rewind 和 clear 等,来更灵活地管理数据。
总的来说,面向缓冲区的 I/O 是一种高效的数据流读写方式;
在流式 I/O 中,每次读写操作都只能处理一个字节。这是因为流式 I/O 将数据看作一个连续的序列,每次读写操作都只能处理一个字节。
例如,在使用 InputStream 类的 read 方法时,会读取下一个字节,并将其作为整数返回。如果要读取多个字节,则必须进行多次调用。同样,在使用 OutputStream 类的 write 方法时,也只能写入一个字节。
相比之下,在面向缓冲区的 I/O 中,可以一次性处理多个字节。这是因为它使用缓冲区来存储数据,可以一次性读写多个字节。
非阻塞 I/O 指的是在读写数据时,如果无法立即完成操作,则不会阻塞线程,而是立即返回。
在 Java NIO 中,非阻塞 I/O 通常是通过将通道设置为非阻塞模式来实现的。在非阻塞模式下,如果无法立即完成读写操作,则会立即返回一个特殊值(通常是 -1)。
举个例子,在使用 SocketChannel 类的 read 方法时,如果在非阻塞模式下调用,则如果无法立即读取数据,则会立即返回 -1。
在 Java NIO 中,通道是一种用于读写数据的对象。它可以看作是一条连接数据源和数据接收器的管道。
通道可以连接不同的数据源,如文件、网络套接字、管道等。在 Java NIO 中,通道的实现类有 FileChannel、SocketChannel、ServerSocketChannel 和 DatagramChannel 等。
通道的主要作用是用于读写数据。例如,可以使用通道将数据从文件读取到内存中,或者将数据从内存写入文件。同时,也可以使用通道将数据从一个网络套接字读取到另一个网络套接字中,或者将数据从一个线程写入另一个县城。
通道还可以用于进行非阻塞 I/O 操作。在非阻塞模式下,如果无法立即完成读写操作,则会立即返回一个特殊值(通常是 -1),而不会阻塞线程。
通道还可以用于进行直接缓冲区传输。直接缓冲区传输指的是直接将缓冲区中的数据读写到通道中,而不经过中间缓存。这样可以避免数据拷贝的操作,提高效率。
总的来说,通道是 Java NIO 中一种重要的抽象,可以用于读写数据、非阻塞 I/O 和直接缓冲区传输等操作。