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

时间:2022-09-09 20:09:57

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

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

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

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

1、字节读写(InputStream/OutputStream)

2、字符读取(FileReader/FileWriter)

3、行读取(BufferedReader/BufferedWriter)

代码(以读取为例):

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
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更有效率。

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
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请参考:http://www.zzvips.com/article/146072.html

个人测试:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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及性能比较详细代码及总结的全部内容,希望对大家有所帮助。感兴趣的朋友可以继续参阅本站其他相关专题,如有不足之处,欢迎留言指出。感谢朋友们对本站的支持!

原文链接:http://blog.csdn.net/chenleixing/article/details/44207469