Java文件读写IO/NIO及性能比较详细代码及总结

 更新时间:2017年12月23日 15:01:22   作者:Java我人生  
这篇文章主要介绍了Java文件读写IO/NIO及性能比较详细代码及总结,具有一定借鉴价值,需要的朋友可以参考下。

干Java这么久,一直在做WEB相关的项目,一些基础类差不多都已经忘记。经常想得捡起,但总是因为一些原因,不能如愿。

其实不是没有时间,只是有些时候疲于总结,今得空,下定决心将丢掉的都给捡起来。

文件读写是一个在项目中经常遇到的工作,有些时候是因为维护,有些时候是新功能开发。我们的任务总是很重,工作节奏很快,快到我们不能停下脚步去总结。

文件读写有以下几种常用的方法

1、字节读写(InputStream/OutputStream)

2、字符读取(FileReader/FileWriter)

3、行读取(BufferedReader/BufferedWriter)

代码(以读取为例):

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
/** 
 * <b>文件读取类</b><br /> 
 * 1、按字节读取文件内容<br /> 
 * 2、按字符读取文件内容<br /> 
 * 3、按行读取文件内容<br /> 
 * @author qin_xijuan 
 * 
 */
public class FileOperate {
	private static final String FILE_PATH = "d:/work/the List of Beautiful Music.txt";
	/** 
   * 以字节为单位读取文件内容 
   * @param filePath:需要读取的文件路径 
   */
	public static void readFileBybyte(String filePath) {
		File file = new File(filePath);
		// InputStream:此抽象类是表示字节输入流的所有类的超类。 
		InputStream ins = null ;
		try{
			// FileInputStream:从文件系统中的某个文件中获得输入字节。 
			ins = new FileInputStream(file);
			int temp ;
			// read():从输入流中读取数据的下一个字节。 
			while((temp = ins.read())!=-1){
				System.out.write(temp);
			}
		}
		catch(Exception e){
			e.getStackTrace();
		}
		finally{
			if (ins != null){
				try{
					ins.close();
				}
				catch(IOException e){
					e.getStackTrace();
				}
			}
		}
	}
	/** 
   * 以字符为单位读取文件内容 
   * @param filePath 
   */
	public static void readFileByCharacter(String filePath){
		File file = new File(filePath);
		// FileReader:用来读取字符文件的便捷类。 
		FileReader reader = null;
		try{
			reader = new FileReader(file);
			int temp ;
			while((temp = reader.read()) != -1){
				if (((char) temp) != '\r') {
					System.out.print((char) temp);
				}
			}
		}
		catch(IOException e){
			e.getStackTrace();
		}
		finally{
			if (reader != null){
				try {
					reader.close();
				}
				catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
	/** 
   * 以行为单位读取文件内容 
   * @param filePath 
   */
	public static void readFileByLine(String filePath){
		File file = new File(filePath);
		// BufferedReader:从字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取。 
		BufferedReader buf = null;
		try{
			// FileReader:用来读取字符文件的便捷类。 
			buf = new BufferedReader(new FileReader(file));
			// buf = new BufferedReader(new InputStreamReader(new FileInputStream(file))); 
			String temp = null ;
			while ((temp = buf.readLine()) != null ){
				System.out.println(temp);
			}
		}
		catch(Exception e){
			e.getStackTrace();
		}
		finally{
			if(buf != null){
				try{
					buf.close();
				}
				catch (IOException e) {
					e.getStackTrace();
				}
			}
		}
	}
	public static void main(String args[]) {
		readFileBybyte(FILE_PATH);
		readFileByCharacter(FILE_PATH);
		readFileByLine(FILE_PATH);
	}
}

//-----------------------------------------------------------------分割线-----------------------------------------------------------------------------

再经过两位同行的提点下,我对之前写的文件做了点修改,并通过读写一个1.2M的文本文件来测试各方法的性能。从多次测试结果来看,行读写却是是Java.nio更有效率。

经过修改之后的代码如下:

package com.waddell.basic;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
/** 
 * <b>文件读取类</b><br /> 
 * 1、按字节读取文件内容<br /> 
 * 2、按字符读取文件内容<br /> 
 * 3、按行读取文件内容<br /> 
 * 
 * @author qin_xijuan 
 * 
 */
public class FileOperate {
	private static final String FILE_PATH = "d:/work/jipinwodi.txt";
	/** 
   * 以字节为单位读写文件内容 
   * 
   * @param filePath 
   *      :需要读取的文件路径 
   */
	public static void readFileBybyte(String filePath) {
		File file = new File(filePath);
		// InputStream:此抽象类是表示字节输入流的所有类的超类。 
		InputStream ins = null;
		OutputStream outs = null;
		try {
			// FileInputStream:从文件系统中的某个文件中获得输入字节。 
			ins = new FileInputStream(file);
			outs = new FileOutputStream("d:/work/readFileByByte.txt");
			int temp;
			// read():从输入流中读取数据的下一个字节。 
			while ((temp = ins.read()) != -1) {
				outs.write(temp);
			}
		}
		catch (Exception e) {
			e.getStackTrace();
		}
		finally {
			if (ins != null && outs != null) {
				try {
					outs.close();
					ins.close();
				}
				catch (IOException e) {
					e.getStackTrace();
				}
			}
		}
	}
	/** 
   * 以字符为单位读写文件内容 
   * 
   * @param filePath 
   */
	public static void readFileByCharacter(String filePath) {
		File file = new File(filePath);
		// FileReader:用来读取字符文件的便捷类。 
		FileReader reader = null;
		FileWriter writer = null;
		try {
			reader = new FileReader(file);
			writer = new FileWriter("d:/work/readFileByCharacter.txt");
			int temp;
			while ((temp = reader.read()) != -1) {
				writer.write((char)temp);
			}
		}
		catch (IOException e) {
			e.getStackTrace();
		}
		finally {
			if (reader != null && writer != null) {
				try {
					reader.close();
					writer.close();
				}
				catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
	/** 
   * 以行为单位读写文件内容 
   * 
   * @param filePath 
   */
	public static void readFileByLine(String filePath) {
		File file = new File(filePath);
		// BufferedReader:从字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取。 
		BufferedReader bufReader = null;
		BufferedWriter bufWriter = null;
		try {
			// FileReader:用来读取字符文件的便捷类。 
			bufReader = new BufferedReader(new FileReader(file));
			bufWriter = new BufferedWriter(new FileWriter("d:/work/readFileByLine.txt"));
			// buf = new BufferedReader(new InputStreamReader(new 
			// FileInputStream(file))); 
			String temp = null;
			while ((temp = bufReader.readLine()) != null) {
				bufWriter.write(temp+"\n");
			}
		}
		catch (Exception e) {
			e.getStackTrace();
		}
		finally {
			if (bufReader != null && bufWriter != null) {
				try {
					bufReader.close();
					bufWriter.close();
				}
				catch (IOException e) {
					e.getStackTrace();
				}
			}
		}
	}
	/** 
   * 使用Java.nio ByteBuffer字节将一个文件输出至另一文件 
   * 
   * @param filePath 
   */
	public static void readFileByBybeBuffer(String filePath) {
		FileInputStream in = null;
		FileOutputStream out = null;
		try {
			// 获取源文件和目标文件的输入输出流  
			in = new FileInputStream(filePath);
			out = new FileOutputStream("d:/work/readFileByBybeBuffer.txt");
			// 获取输入输出通道 
			FileChannel fcIn = in.getChannel();
			FileChannel fcOut = out.getChannel();
			ByteBuffer buffer = ByteBuffer.allocate(1024);
			while (true) {
				// clear方法重设缓冲区,使它可以接受读入的数据 
				buffer.clear();
				// 从输入通道中将数据读到缓冲区 
				int r = fcIn.read(buffer);
				if (r == -1) {
					break;
				}
				// flip方法让缓冲区可以将新读入的数据写入另一个通道  
				buffer.flip();
				fcOut.write(buffer);
			}
		}
		catch (Exception e) {
			e.printStackTrace();
		}
		finally {
			if (in != null && out != null) {
				try {
					in.close();
					out.close();
				}
				catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
	public static long getTime(){
		return System.currentTimeMillis();
	}
	public static void main(String args[]) {
		long time1 = getTime() ;
		// readFileByByte(FILE_PATH);// 8734,8281,8000,7781,8047 
		// readFileByCharacter(FILE_PATH);// 734, 437, 437, 438, 422 
		// readFileByLine(FILE_PATH);// 110, 94, 94, 110, 93 
		readFileByBybeBuffer(FILE_PATH);
		// 125, 78, 62, 78, 62 
		long time2 = getTime() ;
		System.out.println(time2-time1);
	}
}

在main方法中,调用各方法之后,有五组数据,分辨是我5次读写文件测试出来的时间(毫秒)。

关于Java.nio请参考:https://www.jb51.net/article/131338.htm

个人测试:

public static void main(String args[]) {
	long time1 = getTime() ;
	//     readFileByByte(FILE_PATH);   //2338,2286 
	//     readFileByCharacter(FILE_PATH);//160,162,158 
	//     readFileByLine(FILE_PATH);   //46,51,57 
	//    readFileByBybeBuffer(FILE_PATH);//19,18,17 
	//    readFileByBybeBuffer(FILE_PATH);//2048: 11,13 
	//    readFileByBybeBuffer(FILE_PATH);//1024*100 100k,711k: 6,6 
	//    readFileByBybeBuffer(FILE_PATH);//1024*100 100k,1422k: 7 
	//    readFileByBybeBuffer(FILE_PATH);//1024*100 100k,9951k: 49,48 
	//    readFileByBybeBuffer(FILE_PATH);//1024*1000 1M,711k: 7,7 
	//    readFileByBybeBuffer(FILE_PATH);//1024*1000 1M,1422k: 7,8 
	//    readFileByBybeBuffer(FILE_PATH);//1024*1000 1M,9951k: 48,49 
	//    readFileByBybeBuffer(FILE_PATH);//1024*10000 10M,711k: 21,13,17 
	//    readFileByBybeBuffer(FILE_PATH);//1024*10000 10M,1422k: 16,17,14,15 
	//    readFileByBybeBuffer(FILE_PATH);//1024*10000 10M,9951k:64,60 
	long time2 = getTime() ;
	System.out.println(time2-time1);
}

总结

以上就是本文关于Java文件读写IO/NIO及性能比较详细代码及总结的全部内容,希望对大家有所帮助。感兴趣的朋友可以继续参阅本站其他相关专题,如有不足之处,欢迎留言指出。感谢朋友们对本站的支持!

相关文章

  • JAVA中JNI的简单使用分享

    JAVA中JNI的简单使用分享

    这篇文章介绍了JAVA中JNI的简单使用,有需要的朋友可以参考一下
    2013-10-10
  • Java终止线程的两种方法

    Java终止线程的两种方法

    本文主要介绍了Java终止线程的两种方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-07-07
  • Java基础知识之CharArrayReader流的使用

    Java基础知识之CharArrayReader流的使用

    这篇文章主要介绍了Java基础知识之CharArrayReader流的使用,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-12-12
  • java8 利用reduce实现将列表中的多个元素的属性求和并返回操作

    java8 利用reduce实现将列表中的多个元素的属性求和并返回操作

    这篇文章主要介绍了java8 利用reduce实现将列表中的多个元素的属性求和并返回操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-08-08
  • RestTemplate响应中如何获取输入流InputStream

    RestTemplate响应中如何获取输入流InputStream

    这篇文章主要介绍了RestTemplate响应中如何获取输入流InputStream问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-01-01
  • Springboot集成Ehcache3实现本地缓存的配置方法

    Springboot集成Ehcache3实现本地缓存的配置方法

    EhCache是一个纯Java的进程内缓存框架,是 Hibernate 中默认的 CacheProvider,同Redis一样,EhCache 不是纯内存缓存,它支持基于内存和磁盘的二级缓存,本文介绍Springboot集成Ehcache3实现本地缓存的配置方法,感兴趣的朋友一起看看吧
    2024-04-04
  • 基于@ComponentScan注解及其XML配置方式

    基于@ComponentScan注解及其XML配置方式

    这篇文章主要介绍了基于@ComponentScan注解及其XML配置方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-09-09
  • Java中Velocity快速对变量中的引号特殊字符进行转义

    Java中Velocity快速对变量中的引号特殊字符进行转义

    Velocity是一个基于Java的模板引擎,与Freemarker类似,这篇文章主要介绍了Java中Velocity如何对变量中的引号特殊字符进行转义,主要记录一下在使用中碰到的要对引号特殊字符进行转义的问题,需要的朋友可以参考下
    2023-07-07
  • java String到底有多长?String超出长度该如何解决

    java String到底有多长?String超出长度该如何解决

    在Java中,由于字符串常量池的存在,String常量长度限制取决于String常量在常量池中的存储大小,下面这篇文章主要给大家介绍了关于java String到底有多长?String超出长度该如何解决的相关资料,需要的朋友可以参考下
    2023-01-01
  • Trie树(字典树)的介绍及Java实现

    Trie树(字典树)的介绍及Java实现

    Trie树,又称字典树或前缀树,关于它的结构就不详细介绍了。Trie树在单词统计、前缀匹配等很多方面有很大用处。下面这篇文章主要介绍了Trie树,以及Java实现如何Trie树,有需要的朋友可以参考借鉴,下面来一起看看吧。
    2017-02-02

最新评论