Java文件读写IO/NIO及性能比较详细代码及总结
作者:Java我人生 发布时间:2021-11-28 12:56:30
标签: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);
}
来源:http://blog.csdn.net/chenleixing/article/details/44207469


猜你喜欢
- 先看下面的这组字符,如果输出来,它是无法靠右对齐: Source Codestring[] s1 = { "300",
- 1.介绍有时候我们在Linux中运行Java程序时,需要调用一些Shell命令和脚本。而Runtime.getRuntime().exec(
- 本文实例为大家分享了java文件上传和预览实现代码,供大家参考,具体内容如下1、下载uploadify插件2、index.html<!
- 一、概述1.目标:要在Tank的move()方法做时间代理及日志代理(可以设想以后还要增加很多代理处理),且代理间的顺序可活更换2.思路:(
- 主要是应对这种需求:软件只允许启动一次。将这个问题转化一下,可以这样描述:对于一个软件,在启动一个进程之后,不允许启动其它进程,如果第二次打
- 最近在做一个搜索相关的项目,需要爬取网络上的一些链接存储到索引库中,虽然有很多开源的强大的爬虫框架,但本着学习的态度,自己写了一个简单的网络
- 用户退出应用前给出一个提示是很有必要的,因为可能是用户并不真的想退出,而只是一不小心按下了返回键,大部分应用的做法是在应用退出去前给出一个D
- 什么是自旋锁说道自旋锁就要从多线程下的锁机制说起,由于在多处理器系统环境中有些资源因为其有限性,有时需要互斥访问(mutual exclus
- 本文实例讲述了C#实现的上传图片、保存图片、加水印、生成缩略图功能。分享给大家供大家参考,具体如下:伴随移动设备地普及,处理图片、视频等需求
- 黑白棋介绍黑白棋,又叫苹果棋,最早流行于西方国家。游戏通过相互翻转对方的棋子,最后以棋盘上谁的棋子多来判断胜负。黑白棋非常易于上手,但精通则
- 引言本文收集了我在看Lucene源码中遇到的所有的对单值(int,long,float,double)的压缩算法,可能一种类型针对不同的场景
- 这篇文章主要介绍了Java判断主机是否能ping通代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要
- 1、问题起因最近做项目时遇到了需要多用户之间通信的问题,涉及到了WebSocket握手请求,以及集群中WebSocket Session共享
- 以前使用MyEclipse已经习惯了,后来改成Eclipse感觉怪怪的。在创建web项目之前首先配置好jdk环境和tomcat环境(即在开发
- Shiro介绍Shiro是一款安全框架,主要的三个类Subject、SecurityManager、RealmSubject:表示当前用户S
- java字段值为null,不返回该字段类上打注解@JsonSerialize(include = JsonSerialize.Inclusi
- 本文实例讲述了WPF的ListView控件自定义布局用法。分享给大家供大家参考,具体如下:概要:以源码的形式贴出,免得忘记后,再到网上查资料
- 又遇到了回调函数,这次打算写下来分享一下。所谓回调函数,或者在面向对象语言里叫回调方法,简单点讲,就是回头在某个时间(事件发生)被调用的函数
- 本文实例为大家分享了java实现TCPSocket聊天室功能的相关代码,供大家参考,具体内容如下1.TCPserver.javaimport
- 详解JDK中ExecutorService与Callable和Future对线程的支持1、代码背景: 假