`
heipark
  • 浏览: 2097556 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

用java内存映射实现读取文件行(readline)

    博客分类:
  • Java
 
阅读更多

下面代码使用两种方式读取日志文件,一种是流方式,一种是内存映射:

 

 

 

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.CharBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.util.Scanner;
import java.util.zip.GZIPInputStream;

public class Test {
	static String path = "D:\\log\\proclog\\loganalysis\\0108161331_CHN-MY-1_1021235501.log";

	public static void main(String[] s) throws IOException {
		stream();
		mem();
	}

	public static void stream() throws FileNotFoundException, IOException {
		Long startTime = System.currentTimeMillis();
		BufferedReader reader = getReader(new File(path));

		String line;
		while ((line = reader.readLine()) != null) {
			// 空转
		}
		Long estimatedTime = System.currentTimeMillis() - startTime;
		System.out.printf("stream Diff: %d ms\n", estimatedTime);

	}

	public static BufferedReader getReader(File f) throws FileNotFoundException, IOException {
		BufferedReader reader = null;
		if (f.getName().endsWith(".gz")) {
			reader = new BufferedReader(new InputStreamReader(new GZIPInputStream(new FileInputStream(f))));
		} else {
			reader = new BufferedReader(new InputStreamReader(new FileInputStream(f)));
		}
		return reader;
	}

	public static void mem() throws IOException {
		Long startTime = System.currentTimeMillis();
		FileChannel fc = new FileInputStream(path).getChannel();
		MappedByteBuffer byteBuffer = fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size());
		//Charset charset = Charset.forName("US-ASCII");
		Charset charset = Charset.forName("iso-8859-1");
		CharsetDecoder decoder = charset.newDecoder();
		CharBuffer charBuffer = decoder.decode(byteBuffer);
		Scanner sc = new Scanner(charBuffer).useDelimiter(System.getProperty("line.separator"));
		while (sc.hasNext()) {
			sc.next();
		}
		fc.close();
		Long estimatedTime = System.currentTimeMillis() - startTime;
		System.out.printf("mem Diff: %d ms", estimatedTime);
	}
}

 

 

 

 输出:
stream Diff: 147 ms
mem Diff: 2470 ms

 

从输出来看流方式要远远快于内存映射读取,看来逐行读取文本还是继续使用steam api吧。

 

PS. 测试文件大小23MB,使用一个100MB的文件,mem方式报内存溢出,有点尴尬,先做个记号吧。

 

参考:

 

http://hi.baidu.com/limin040206/blog/item/92763dfcd301ff0008244d48.html

http://jiangzhengjun.iteye.com/blog/515745

http://stackoverflow.com/questions/1045632/bufferedreader-for-large-bytebuffer

http://www.javakb.com/Uwe/Forum.aspx/java-programmer/7117/Reading-lines-of-text-from-a-MappedByteBuffer

 

-- end --

 

分享到:
评论
7 楼 cyb_rc 2013-11-18  
PS. 测试文件大小23MB,使用一个100MB的文件,mem方式报内存溢出,有点尴尬,先做个记号吧。

至于这个,mem默认大小是跟堆的大小一样,可以自己设置mem大小
6 楼 cyb_rc 2013-11-18  
至于这个

PS. 测试文件大小23MB,使用一个100MB的文件,mem方式报内存溢出,有点尴尬,先做个记号吧。
5 楼 cyb_rc 2013-11-18  
映射方式 输出的地方时间消耗太大

映射文件 速度比流快很多,文件越大越明显 
4 楼 test_lockxxx 2012-02-08  
我估计卡在这里:

Scanner sc = new Scanner(charBuffer).useDelimiter(System.getProperty("line.separator"));  

3 楼 test_lockxxx 2012-02-08  
拿 BufferedReader 与 MappedByteBuffer  相比,这本身就不公平。

至少也应该拿 BufferedInputStream 与 MappedByteBuffer 相比。
2 楼 heipark 2011-10-18  
lindakun 写道
请问楼主,逐行读取有没有更快的方法呢?

到目前为止除了BufferedReader,我不知道用其它了,这块sun/oracle已经做过优化,踏实用吧,如果还有问题,或许要转变解决问题的思路。
1 楼 lindakun 2011-09-29  
请问楼主,逐行读取有没有更快的方法呢?

相关推荐

    java io读取文件

    - Java的`MappedByteBuffer`类允许将文件映射到内存,使得文件操作如同访问内存一样快速,适合处理大型文件。 9. **大数据量文件读取策略** - **分块读取**:对于大文件,不一次性加载到内存,而是按需分块读取。...

    Java读取Ini文件

    在Java中,没有内置的库来直接处理Ini文件,但我们可以利用Java的I/O流和字符串处理功能来实现读取Ini文件的功能。下面将详细介绍如何在Java中读取Ini文件。 首先,我们需要了解Ini文件的基本结构。Ini文件由多个节...

    java读取超大文本文件

    在处理大数据量的文本文件时,Java 提供了多种方式来实现高效、低内存占用的文件读取操作。本文将围绕标题“java读取超大文本文件”及其相关描述和部分代码片段进行深入解析,探讨如何有效地读取大型文本文件。 ###...

    java 读取文件方法的总结

    这段代码将映射整个文件到内存,然后逐字节读取。 这些方法各有优缺点,开发者应根据实际需求选择最合适的读取方式。例如,字节流适合二进制文件,字符流适合文本文件,而NIO则适用于大文件和高并发场景。理解这些...

    jsp+java类+servlet实现文件读取、写入的功能.pdf

    ### jsp+java类+servlet实现文件读取、写入的功能 #### 一、概述 在Web开发领域,特别是基于Java的技术栈中,文件的读取与写入是一项基础但非常重要的功能。本文将详细介绍如何利用JSP、Java类以及Servlet技术在...

    java读取ini文件

    本篇将深入探讨如何在Java中读取和操作INI文件,以及相关工具的使用。 首先,Java标准库并没有直接支持读写INI文件的API,因此我们需要依赖第三方库或者自定义方法来实现这一功能。在给定的链接中,博主提供了有关...

    有效率的读取大文件(2G)

    5. **内存映射文件**:Java的`MappedByteBuffer`实现了内存映射文件功能,它将文件的部分或全部映射到进程的虚拟内存空间,使得可以直接通过内存访问文件,避免了I/O操作。但是需要注意,如果文件过大,可能会导致...

    NIO按行读取数据

    - 文件映射可能导致内存占用增加,尤其是在处理大文件时,因此需要权衡内存使用和性能提升之间的平衡。 总的来说,上述代码提供了一个自定义的NIO解决方案来按行读取文件,尽管Java NIO本身并不直接支持这个功能。...

    读大文件Java

    `Files.lines()`方法可以创建一个文件行的流,便于使用流式操作。 ```java try (Stream<String> lines = Files.lines(Paths.get("largefile.txt"))) { lines.forEach(System.out::println); } ``` Spliterator...

    Java IO 基础操作(文件读写和移动)

    `java.nio`包下的`FileChannel`和`Files`类提供了更高级的文件操作,如映射内存到文件(MMap),以及异步文件操作。 例如,使用`Files`类移动文件: ```java Path sourcePath = Paths.get("sourceFile.txt"); Path...

    java电子考勤系统(读CSV文件)

    在项目`java1.java`和`java2.java`中,可能分别实现了读取文件和处理数据的不同部分,或者对原始代码进行了优化或功能扩展。通过分析这些文件,你可以深入理解如何在实际项目中处理CSV数据,以及如何构建一个简单的...

    不同类型文件读取工具类

    - **FileReader**与**InputStreamReader**:两者结合使用,可以以字符流的方式读取文件,FileReader用于处理字符流,InputStreamReader处理字节流。 2. **二进制文件读取**: - **FileInputStream**:Java的...

    Java读取txt文件和写入txt文件的简单实例

    本文将详细介绍如何使用Java来读取和写入TXT文件,通过一个简单的实例来帮助理解这个过程。 首先,我们需要引入相关的Java IO类库,这包括`File`、`InputStreamReader`、`BufferedReader`、`FileOutputStream`、`...

    java处理各种文件代码

    5. **FileChannel**:`java.nio.channels.FileChannel`接口提供了一种更高效的方式处理文件,支持大块数据的传输和内存映射。`transferTo()`和`transferFrom()`方法可以实现文件间的高效复制。 6. **NIO (New Input...

    java读取本地json文件.docx

    - 使用Java的`java.io`包中的`FileReader`和`BufferedReader`类来读取文件内容。例如: ```java File file = new File("E:\\work\\json\\xx.json"); FileReader fr = new FileReader(file); BufferedReader br ...

    JAVA_file.rar_操作 文件

    使用`BufferedReader`,我们可以通过`readLine()`方法逐行读取文件,而`Scanner`则提供了更灵活的方式,可以按字符、单词或整行读取。 写入文件时,可以使用`BufferedWriter`或者`PrintWriter`。`BufferedWriter`...

    计算机等级考试二级java模拟题三.pdf

    `BufferedReader` 是一个字符流类,用于提高读取文本文件的效率,`readLine()` 方法可以读取文件的一行内容。 12. 对于数据文件进行缓冲输入操作,通常使用 `BufferedInputStream` 类。在题目提供的句子中,下划线...

    java实现倒排索引表的布尔查询

    可以使用`BufferedReader`类来逐行读取文件,对每一行进行分词处理。 2. **分词**:对每一行内容进行分词,可以使用Java的内置字符串操作,如`split()`函数,或者使用第三方库如Apache Lucene的Analyzer进行更复杂的...

    多种方式读文件内容

    除了上述的基本方法,还有高级技术如内存映射文件(Memory-Mapped Files)和异步读取。内存映射文件允许将整个文件映射到进程的虚拟地址空间,简化了大文件处理。异步读取则在多线程和并发环境中提高性能,避免阻塞...

    java实时监控文件行尾内容的实现

    } } }}总结Java实现实时监控文件行尾内容的关键在于使用`java.nio.file.WatchService`接口。这个接口允许我们注册到某个目录,监听文件系统中的事件,比如文件的创建、修改和删除。在这个例子中,我们关注的是文件...

Global site tag (gtag.js) - Google Analytics