做日志分析服务中,需要对文本文件作大量的读写和备份操作,对性能要求比较高,于是对IO和NIO的文件操作类做测试。
IO这里指java“旧”的IO操作。
对NIO有过了解的朋友都知道:NIO对文件操作是通过FileInputStream、FileOutputStream或者RandomAccessFile对象的getChannel()方法获得一个FileChannel,FileChannel与ByteBuffer建立联系来完成操作。ByteBuffer是字节缓冲区。顾名思义,ByteBuffer是操作的是缓存在内存中的字节。
在整个测试过程中,发现使用NIO的ByteBuffer无论是读还是写文件都比“旧”IO性能要高,但是由于NIO操作的是字节,而在我们中国使用最多的是GBK或者UTF-8的字符,这就出现了一个矛盾,把字符转换为字节时的大量消耗,几乎抵消了NIO对于“旧”IO的优势。
也许你会问NIO中不是有CharBuffer,使用NIO的对字符操作呀?很遗憾的告诉你,NIO提供的FileChannel类的read和write方法中参数都是ByteBuffer,而没有对CharBuffer的支持,这个也可能是个不足的地方。
由于做日志分析服务,对文本文件按行读readLine(),封装字节流和NIO后的形成的readLine()并不比BufferedRead的readLine快。
还有一个比较普遍的说话:读的时候下来了,内存上去了。内存下来了,读的时间上去了。
总结:1 如果读写是瓶颈,读选择NIO非直接字节缓冲区,写选择NIO的直接字节缓冲区。不过要注意编码。
2 如果不想考虑太多的问题,使用BufferedReader和BufferedWriter。
3 如果操作的内容全部是英文,那还是选择NIO撒。
温情提示:众所周知,UTF-8是变长编码,一个字符占1-4字节都有可能。
API内容:
BufferedReader :从字符输入流中读取文本,缓冲各个字符,从而提供字符、数组和行的高效读取。可以指定缓冲区的大小,或者可使用默认的大小。大多数情况下,默认值就足够大了。
通常,Reader 所作的每个读取请求都会导致对基础字符或字节流进行相应的读取请求。因此,建议用 BufferedReader 包装所有其 read() 操作可能开销很高的 Reader(如 FileReader 和 InputStreamReader)。例如,
BufferedReader in = new BufferedReader(new FileReader("foo.in"));
将缓冲指定文件的输入。如果没有缓冲,则每次调用 read() 或 readLine() 都会导致从文件中读取字节,并将其转换为字符后返回,而这是极其低效的。
可以对使用 DataInputStream 进行按原文输入的程序进行本地化,方法是用合适的 BufferedReader 替换每个 DataInputStream。
-----------------------------------------------------
BufferedWriter :将文本写入字符输出流,缓冲各个字符,从而提供单个字符、数组和字符串的高效写入。可以指定缓冲区的大小,或者接受默认的大小。在大多数情况下,默认值就足够大了。该类提供了 newLine() 方法,它使用平台自己的行分隔符概念,此概念由系统属性 line.separator 定义。并非所有平台都使用新行符 ('\n') 来终止各行。因此调用此方法来终止每个输出行要优于直接写入新行符。
通常 Writer 将其输出立即发送到基础字符或字节流。除非要求提示输出,否则建议用 BufferedWriter 包装所有其 write() 操作可能开销很高的 Writer(如 FileWriters 和 OutputStreamWriters)。例如,
PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter("foo.out")));
将缓冲 PrintWriter 对文件的输出。如果没有缓冲,则每次调用 print() 方法会导致将字符转换为字节,然后立即写入到文件,而这是极其低效的
-----------------------------------------------
ByteBuffer:缓冲区
直接与 非直接缓冲区
字节缓冲区要么是直接的,要么是非直接的。如果为直接字节缓冲区,则 Java 虚拟机会尽最大努力直接在此缓冲区上执行本机 I/O 操作。也就是说,在每次调用基础操作系统的一个本机 I/O 操作之前(或之后),虚拟机都会尽量避免将缓冲区的内容复制到中间缓冲区中(或从中间缓冲区中复制内容)。
直接字节缓冲区可以通过调用此类的 allocateDirect 工厂方法来创建。此方法返回的缓冲区进行分配和取消分配所需成本通常高于非直接缓冲区。直接缓冲区的内容可以驻留在常规的垃圾回收堆之外,因此,它们对应用程序的内存需求量造成的影响可能并不明显。所以,建议将直接缓冲区主要分配给那些易受基础系统的本机 I/O 操作影响的大型、持久的缓冲区。一般情况下,最好仅在直接缓冲区能在程序性能方面带来明显好处时分配它们。
直接字节缓冲区还可以通过 mapping 将文件区域直接映射到内存中来创建。Java 平台的实现有助于通过 JNI 从本机代码创建直接字节缓冲区。如果以上这些缓冲区中的某个缓冲区实例指的是不可访问的内存区域,则试图访问该区域不会更改该缓冲区的内容,并且将会在访问期间或稍后的某个时间导致抛出不确定的异常。
字节缓冲区是直接缓冲区还是非直接缓冲区可通过调用其 isDirect 方法来确定。提供此方法是为了能够在性能关键型代码中执行显式缓冲区管理。
<!--EndFragment-->
分享到:
相关推荐
例如,`FileReader`和`FileWriter`用于文本文件的读写,`FileInputStream`和`FileOutputStream`用于二进制文件的读写。 **Java NIO API** Java NIO在Java 1.4版本中引入,提供了非阻塞I/O操作,极大地提高了性能。...
BufferedReader是用来读取文本文件的便捷类,而BufferedWriter是用来写入文本文件的便捷类。下面是使用BufferedReader和BufferedWriter实现文件读写的示例代码: ```java public static void readFileByLine(String...
Java IO(Input/Output)和NIO(New IO)是Java平台中用于处理输入和输出操作的核心库。这两个系统提供了不同的方式来读取和写入数据,分别适用于不同类型的场景和需求。 Java IO体系主要基于流(Stream)的概念,...
#### 一、IO与NIO概述 在Java开发中,输入/输出(IO)操作是程序与外部环境交互的重要环节。通过IO操作,程序可以读取外部数据或向外部环境输出数据。Java的IO体系自Java 1.0以来就一直存在,并且随着时间的发展...
根据给定的信息,我们可以深入探讨Java IO操作中的文件读写技术,特别关注如何从一个文本文件中筛选数据并保存到另一个文件中。 ### Java IO读写文件基础 在Java中,进行文件读写的操作通常涉及两个核心包:`java....
这使得处理文本文件变得更加方便。 总的来说,Java IO提供了丰富的类和方法来处理文件的读写操作。RandomAccessFile适用于需要在文件中任意位置进行读写的场景,而BufferedWriter和BufferedReader则提高了文本读写...
FileInputStream和FileOutputStream处理文件读写,而FileReader和FileWriter处理文本文件。 4. **NIO**:非阻塞I/O引入了选择器(Selector)和通道(Channel)的概念,允许单个线程同时处理多个连接,适合高并发...
与传统IO流不同,通道可以同时进行读写操作,且支持非阻塞模式。 4. **Selector**:Selector是NIO的核心组件,它允许单个线程监控多个通道的事件(如连接请求、数据到达等)。通过注册通道到Selector并设置感兴趣的...
首先,要读取一个文本文件,我们可以使用`java.io`包中的`BufferedReader`类。下面是一个基本的读取文件内容的例子: ```java import java.io.BufferedReader; import java.io.FileReader; import java.io....
在Java编程语言中,输入/输出(IO)是处理数据传输的关键部分,特别是在与文件系统交互时。`FileInputStream`和`OutputStream`是Java IO API中的基础类,用于进行原始字节流的读写操作。而`BufferedReader`则是一个...
在Java编程语言中,读写文本文件是常见的操作,这对于数据存储、日志记录或配置文件处理至关重要。这个"基于Java的实例源码-读写文本文件的示例代码.zip"压缩包很可能是包含了几个演示如何在Java中执行这些操作的源...
在Java编程语言中,读取和写入文本文件是常见的任务,这...理解并熟练运用这些知识点,你就能在Java项目中轻松地处理文本文件的读写操作。通过实践提供的示例代码,你可以更好地掌握这些概念,并根据实际需求进行调整。
Java中的IO流是Java核心库java.io中的关键组成部分,它为程序提供了与外部资源交互的能力,包括文件读写、标准设备输入输出等。Java的IO流机制基于流的概念,流可以被视为数据传输的通道,数据按照序列化的方式从...
Java提供了多种IO方式,包括传统的阻塞IO(BIO)、非阻塞IO(NIO)以及异步非阻塞IO(AIO,也称为NIO 2)。 1. **传统阻塞IO(BIO)**: - 基于`java.io`包,主要使用`File`、`InputStream`、`OutputStream`、`...
本文将深入探讨Java中的基本文件操作,包括文件的移动、读写以及文本文件的读写。 首先,让我们从文件操作开始。在Java中,我们可以使用`java.io.File`类来创建、删除、重命名或检查文件是否存在。例如,创建一个新...
在Java编程语言中,读写文本文件是常见的操作,这对于数据存储、日志记录或配置文件处理至关重要。这个"基于Java的源码-读写文本文件的示例代码.zip"压缩包很可能包含了若干个用于演示如何在Java中执行这些操作的源...
在Java编程语言中,读取和写入文本文件是常见的操作,这在处理数据、日志记录、配置文件等方面...这些知识点构成了Java中读写文本文件的基础。通过理解并实践这些示例代码,你可以有效地在Java应用程序中处理文本文件。
在Java编程语言中,读写文本文件是常见的操作,这对于数据存储、日志记录或文件处理等场景至关重要。本示例代码将引导你了解如何在Java中实现这一功能。我们将探讨以下几个关键知识点: 1. **File类**:Java中的`...
`BufferedReader`和`PrintWriter`简化了文本文件的读写,支持读写一行数据。例如: ```java BufferedReader reader = new BufferedReader(new FileReader(file)); PrintWriter writer = new PrintWriter(new ...