zoukankan      html  css  js  c++  java
  • Java文件操作类效率对比

    前言

    众所周知,Java中有多种针对文件的操作类,以面向字节流和字符流可分为两大类,这里以写入为例:

    面向字节流的:FileOutputStream 和 BufferedOutputStream

    面向字符流的:FileWriter 和 BufferedWriter

    近年来发展出New I/O ,也叫NIO,里面又包装了两个类:NewOutputStream 和 NewBufferedWriter

    现在,我们建立测试程序,比较这些类写入文件的性能。

    机器配置

    •   Processor Name: Intel Core i7
    •   Processor Speed: 2.2 GHz
    •   Number of Processors: 1
    •   Total Number of Cores: 4
    •   L2 Cache (per Core): 256 KB
    •   L3 Cache: 6 MB
    •   Memory: 16 GB

    测试程序

    纵向比较:几种文件操作类向文件中写入相同行数的内容(每行内容均为“写入文件Data ”),比较其耗费时间

    横向比较:对于同一个文件操作类,比较写入不同行数内容情况下所耗费时间;本文以2的次方指数级增长行数

      1 import java.io.File;
      2 import java.io.FileOutputStream;
      3 import java.io.*;
      4 import java.nio.file.Files;
      5 import java.nio.file.Paths;
      6 
      7 public class testFileIO {
      8 
      9     public static void testDriver () throws IOException {
     10         int maxlineNum = 100000001;//写入文件的最大行数
     11         int startlineNum = 1;//写入文件的行数
     12         int Multiplying = 2;//行数增长倍率
     13 
     14         long begin = 0L;
     15         long end = 0L;
     16 
     17         //将时间统计写入文件Result.txt中
     18         FileWriter fileWriter = new FileWriter("./Result.txt", true);
     19         BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);
     20 
     21         System.out.println("Test FileOutputStream begin.");
     22         for (int lineNum = startlineNum; lineNum < maxlineNum; lineNum *= Multiplying) {
     23             begin = System.currentTimeMillis();
     24             testFileOutputStream(lineNum);
     25             end = System.currentTimeMillis();
     26             long timeElapse_FileOutputStream = end - begin;
     27             bufferedWriter.write(String.valueOf(timeElapse_FileOutputStream)+"	");
     28         }
     29         System.out.println("Test FileOutputStream end.
    ");
     30 
     31         System.out.println("Test BufferedOutputStream begin.");
     32         bufferedWriter.write("
    ");
     33         for (int lineNum = startlineNum; lineNum < maxlineNum; lineNum *= Multiplying) {
     34             begin = System.currentTimeMillis();
     35             testBufferedOutputStream(lineNum);
     36             end = System.currentTimeMillis();
     37             long timeElapse_BufferedOutputStream = end - begin;
     38             bufferedWriter.write(String.valueOf(timeElapse_BufferedOutputStream)+"	");
     39         }
     40         System.out.println("Test BufferedOutputStream end.
    ");
     41 
     42         System.out.println("Test FileWriter begin.");
     43         bufferedWriter.write("
    ");
     44         for (int lineNum = startlineNum; lineNum < maxlineNum; lineNum *= Multiplying) {
     45             begin = System.currentTimeMillis();
     46             testFileWriter(lineNum);
     47             end = System.currentTimeMillis();
     48             long timeElapse_FileWriter = end - begin;
     49             bufferedWriter.write(String.valueOf(timeElapse_FileWriter)+"	");
     50         }
     51         System.out.println("Test FileWriter end.
    ");
     52 
     53         System.out.println("Test BufferedWriter begin.");
     54         bufferedWriter.write("
    ");
     55         for (int lineNum = startlineNum; lineNum < maxlineNum; lineNum *= Multiplying) {
     56             begin = System.currentTimeMillis();
     57             testBufferedWriter(lineNum);
     58             end = System.currentTimeMillis();
     59             long timeElapse_BufferedWriter = end - begin;
     60             bufferedWriter.write(String.valueOf(timeElapse_BufferedWriter)+"	");
     61         }
     62         System.out.println("Test BufferedWriter end.
    ");
     63 
     64         System.out.println("Test NewOutputStream begin.");
     65         bufferedWriter.write("
    ");
     66         for (int lineNum = startlineNum; lineNum < maxlineNum; lineNum *= Multiplying) {
     67             begin = System.currentTimeMillis();
     68             testNewOutputStream(lineNum);
     69             end = System.currentTimeMillis();
     70             long timeElapse_NewOutputStream = end - begin;
     71             bufferedWriter.write(String.valueOf(timeElapse_NewOutputStream)+"	");
     72         }
     73         System.out.println("Test NewOutputStream end.
    ");
     74 
     75         System.out.println("Test NewBufferedWriter begin.");
     76         bufferedWriter.write("
    ");
     77         for (int lineNum = startlineNum; lineNum < maxlineNum; lineNum *= Multiplying) {
     78             begin = System.currentTimeMillis();
     79             testNewBufferedWriter(lineNum);
     80             end = System.currentTimeMillis();
     81             long timeElapse_NewBufferedWriter = end - begin;
     82             bufferedWriter.write(String.valueOf(timeElapse_NewBufferedWriter)+"	");
     83         }
     84         System.out.println("Test NewOutputStream end.
    ");
     85 
     86         bufferedWriter.close();
     87     }
     88 
     89     /************************** I/O *****************************/
     90     //面向字节
     91     public static void testFileOutputStream (int lineNum) throws IOException {
     92         FileOutputStream fileOutputStream = new FileOutputStream(new File("./testFileOutputStream.txt"));
     93         while (--lineNum > 0) {
     94             fileOutputStream.write("写入文件Data
    ".getBytes());
     95         }
     96         fileOutputStream.close();
     97     }
     98 
     99     public static void testBufferedOutputStream (int lineNum) throws IOException {
    100         FileOutputStream fileOutputStream = new FileOutputStream(new File("./testBufferedOutputStream.txt"));
    101         BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
    102         while (--lineNum > 0) {
    103             bufferedOutputStream.write("写入文件Data
    ".getBytes());
    104         }
    105         bufferedOutputStream.close();
    106     }
    107 
    108     //面向字符
    109     public static void testFileWriter (int lineNum) throws IOException {
    110         FileWriter fileWriter = new FileWriter("./testFileWriter.txt");
    111         while (--lineNum > 0) {
    112             fileWriter.write("写入文件Data
    ");
    113         }
    114         fileWriter.close();
    115     }
    116 
    117     public static void testBufferedWriter (int lineNum) throws IOException {
    118         FileWriter fileWriter = new FileWriter("./testBufferedWriter.txt");
    119         BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);
    120         while (--lineNum > 0) {
    121             bufferedWriter.write("写入文件Data
    ");
    122         }
    123         bufferedWriter.close();
    124     }
    125 
    126 
    127     /************************** NIO ****************************/
    128     public static void testNewOutputStream (int lineNum) throws IOException {
    129         OutputStream outputStream = Files.newOutputStream(Paths.get("./testNewOutputStream.txt"));
    130         while (--lineNum > 0) {
    131             outputStream.write("写入文件Data
    ".getBytes());
    132         }
    133         outputStream.close();
    134     }
    135 
    136     public static void testNewBufferedWriter (int lineNum) throws IOException {
    137         BufferedWriter newBufferedReader = Files.newBufferedWriter(Paths.get("./testNewBufferedWriter.txt"));
    138         while (--lineNum > 0) {
    139             newBufferedReader.write("写入文件Data
    ");
    140         }
    141         newBufferedReader.close();
    142     }
    143 
    144 
    145     public static void main (String[] args) throws IOException {
    146         //多次测试时可清空result.txt文件
    147         FileWriter fileWriter = new FileWriter("./Result.txt");
    148         testDriver();
    149     }
    150 }

    测试结果

    从上图可以看出,写入行数超过20W以上时,FileOutputStream和NewOutputStream耗费时间远远超出其他4个类。为了清晰,让我们放大其他4个类的图:

    可以看出,这4个类中,BufferWriter和NewBufferedWriter所耗费时间更少,但总体差别不是很大。

    让我们再来看看,写入26W行数据以下时的情况:

         

     可以看出,在数据量较小的情况下,这4个类所耗费时间的差异并不是很大,在更小的数据量下,它们的效率几乎没有差别。

    后记

    从以上分析可知(注意横坐标写入行数是指数级增加的),各个类的时间复杂度大致为O(k),其中不同的类的k不同,导致了最终巨大的差异。

    这里只给出了测试结果,并未很深入地分析其底层实现原理,欢迎评论区留言。

    另外,我没有在其他机器测试,有兴趣的小伙伴可以将自己的测试结果发出来,共同进步^_^

    附件

    本次测试数据结果(若看不清,可以将浏览器字体放大,或下载到本地看)

    ~~~~~~~~~~~~~~~~~~~~~分割线~~~~~~~~~~~~~~~~~~~~~~~

    评论区小伙伴“ andorxor”提出:

    XXXOutputStream是用来写二进制的,你把字符串转换成字节数组再写自然就慢了,主要慢在转换的过程。

    因此,将程序修改,提前把字符和字节内容都准备好,再次验证。新程序如下:

      1 import java.io.File;
      2 import java.io.FileOutputStream;
      3 import java.io.*;
      4 import java.nio.file.Files;
      5 import java.nio.file.Paths;
      6 
      7 public class testFileIO {
      8 
      9 
     10     public static void testDriver () throws IOException {
     11         int maxlineNum = 100000001;//写入文件的最大行数
     12         int startlineNum = 1;//写入文件的行数
     13         int Multiplying = 2;//行数增长倍率
     14 
     15         String contentChars = "写入文件Data
    ";//每行的内容(字符流)
     16         byte[] contentBytes = "写入文件Data
    ".getBytes();//每行的内容(字节流)
     17 
     18         long begin = 0L;
     19         long end = 0L;
     20 
     21         //将时间统计写入文件Result.txt中
     22         FileWriter fileWriter = new FileWriter("./Result.txt", true);
     23         BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);
     24 
     25         System.out.println("Test FileOutputStream begin.");
     26         for (int lineNum = startlineNum; lineNum < maxlineNum; lineNum *= Multiplying) {
     27             begin = System.currentTimeMillis();
     28             testFileOutputStream(lineNum,contentBytes);
     29             end = System.currentTimeMillis();
     30             long timeElapse_FileOutputStream = end - begin;
     31             bufferedWriter.write(String.valueOf(timeElapse_FileOutputStream)+"	");
     32         }
     33         System.out.println("Test FileOutputStream end.
    ");
     34 
     35         System.out.println("Test BufferedOutputStream begin.");
     36         bufferedWriter.write("
    ");
     37         for (int lineNum = startlineNum; lineNum < maxlineNum; lineNum *= Multiplying) {
     38             begin = System.currentTimeMillis();
     39             testBufferedOutputStream(lineNum,contentBytes);
     40             end = System.currentTimeMillis();
     41             long timeElapse_BufferedOutputStream = end - begin;
     42             bufferedWriter.write(String.valueOf(timeElapse_BufferedOutputStream)+"	");
     43         }
     44         System.out.println("Test BufferedOutputStream end.
    ");
     45 
     46         System.out.println("Test FileWriter begin.");
     47         bufferedWriter.write("
    ");
     48         for (int lineNum = startlineNum; lineNum < maxlineNum; lineNum *= Multiplying) {
     49             begin = System.currentTimeMillis();
     50             testFileWriter(lineNum,contentChars);
     51             end = System.currentTimeMillis();
     52             long timeElapse_FileWriter = end - begin;
     53             bufferedWriter.write(String.valueOf(timeElapse_FileWriter)+"	");
     54         }
     55         System.out.println("Test FileWriter end.
    ");
     56 
     57         System.out.println("Test BufferedWriter begin.");
     58         bufferedWriter.write("
    ");
     59         for (int lineNum = startlineNum; lineNum < maxlineNum; lineNum *= Multiplying) {
     60             begin = System.currentTimeMillis();
     61             testBufferedWriter(lineNum,contentChars);
     62             end = System.currentTimeMillis();
     63             long timeElapse_BufferedWriter = end - begin;
     64             bufferedWriter.write(String.valueOf(timeElapse_BufferedWriter)+"	");
     65         }
     66         System.out.println("Test BufferedWriter end.
    ");
     67 
     68         System.out.println("Test NewOutputStream begin.");
     69         bufferedWriter.write("
    ");
     70         for (int lineNum = startlineNum; lineNum < maxlineNum; lineNum *= Multiplying) {
     71             begin = System.currentTimeMillis();
     72             testNewOutputStream(lineNum,contentBytes);
     73             end = System.currentTimeMillis();
     74             long timeElapse_NewOutputStream = end - begin;
     75             bufferedWriter.write(String.valueOf(timeElapse_NewOutputStream)+"	");
     76         }
     77         System.out.println("Test NewOutputStream end.
    ");
     78 
     79         System.out.println("Test NewBufferedWriter begin.");
     80         bufferedWriter.write("
    ");
     81         for (int lineNum = startlineNum; lineNum < maxlineNum; lineNum *= Multiplying) {
     82             begin = System.currentTimeMillis();
     83             testNewBufferedWriter(lineNum,contentChars);
     84             end = System.currentTimeMillis();
     85             long timeElapse_NewBufferedWriter = end - begin;
     86             bufferedWriter.write(String.valueOf(timeElapse_NewBufferedWriter)+"	");
     87         }
     88         System.out.println("Test NewOutputStream end.
    ");
     89 
     90         bufferedWriter.close();
     91     }
     92 
     93     /************************** I/O *****************************/
     94     //面向字节
     95     public static void testFileOutputStream (int lineNum, byte[] content) throws IOException {
     96         FileOutputStream fileOutputStream = new FileOutputStream(new File("./testFileOutputStream.txt"));
     97         while (--lineNum > 0) {
     98             fileOutputStream.write(content);
     99         }
    100         fileOutputStream.close();
    101     }
    102 
    103     public static void testBufferedOutputStream (int lineNum, byte[] content) throws IOException {
    104         FileOutputStream fileOutputStream = new FileOutputStream(new File("./testBufferedOutputStream.txt"));
    105         BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
    106         while (--lineNum > 0) {
    107             bufferedOutputStream.write(content);
    108         }
    109         bufferedOutputStream.close();
    110     }
    111 
    112     //面向字符
    113     public static void testFileWriter (int lineNum, String content) throws IOException {
    114         FileWriter fileWriter = new FileWriter("./testFileWriter.txt");
    115         while (--lineNum > 0) {
    116             fileWriter.write(content);
    117         }
    118         fileWriter.close();
    119     }
    120 
    121     public static void testBufferedWriter (int lineNum, String content) throws IOException {
    122         FileWriter fileWriter = new FileWriter("./testBufferedWriter.txt");
    123         BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);
    124         while (--lineNum > 0) {
    125             bufferedWriter.write(content);
    126         }
    127         bufferedWriter.close();
    128     }
    129 
    130 
    131     /************************** NIO ****************************/
    132     public static void testNewOutputStream (int lineNum, byte[] content) throws IOException {
    133         OutputStream outputStream = Files.newOutputStream(Paths.get("./testNewOutputStream.txt"));
    134         while (--lineNum > 0) {
    135             outputStream.write(content);
    136         }
    137         outputStream.close();
    138     }
    139 
    140     public static void testNewBufferedWriter (int lineNum,String content) throws IOException {
    141         BufferedWriter newBufferedReader = Files.newBufferedWriter(Paths.get("./testNewBufferedWriter.txt"));
    142         while (--lineNum > 0) {
    143             newBufferedReader.write(content);
    144         }
    145         newBufferedReader.close();
    146     }
    147 
    148 
    149     public static void main (String[] args) throws IOException {
    150         //多次测试时可清空result.txt文件
    151         FileWriter fileWriter = new FileWriter("./Result.txt");
    152         testDriver();
    153     }
    154 }
    View Code

    结果为:

    可以看出和前面的案例几乎没有差异(图就不画了)。

    所以XXXOutputStream效率低的原因并不是字符串转换成字节数组,而是其本身的实现方式所致。

    ~~~~~~~~~~~~~~~~~~~~~分割线:底层实现原理浅谈~~~~~~~~~~~~~~~~~~~~~~~

    其实,计算机中都是针对字节操作的(即字符都要经过编码转换为字节),那么问题来了,FileOutputStream为什么比FileWriter(FileWriter内部还有FileOutputStream转换操作,具体看源码)还要慢呢?且慢,让我们把写入文件的数据改一下:

      1 import java.io.File;
      2 import java.io.FileOutputStream;
      3 import java.io.*;
      4 import java.nio.file.Files;
      5 import java.nio.file.Paths;
      6 
      7 public class testFileIO {
      8 
      9 
     10     public static void testDriver () throws IOException {
     11         int maxlineNum = 500001;//写入文件的最大行数
     12         int startlineNum = 1;//写入文件的行数
     13         int Multiplying = 2;//行数增长倍率
     14 
     15         String baseContent = "背景
    " +
     16             "考虑以下场景:
    " +
     17             "
    " +
     18             "InfoTable(信息表):
    " +
     19             "
    " +
     20             "Name	Gender	Age	Score
    " +
     21             "张三	男	21	90
    " +
     22             "李四	女	20	87
    " +
     23             "王五	男	22	92
    " +
     24             "赵六	女	19	94
    " +
     25             "孙七	女	23	88
    " +
     26             "周八	男	20	91
    " +
     27             "StatusTable(状态表,指是否有在考试之前复习):
    " +
     28             "
    " +
     29             "Name	hasReview
    " +
     30             "张三	是
    " +
     31             "李四	否
    " +
     32             "王五	是
    " +
     33             "赵六	是
    " +
     34             "孙七	否
    " +
     35             "周八	是
    " +
     36             "现在,我想知道所有复习过的学生的成绩,可以利用mysql中的子查询来实现:
    " +
     37             "
    " +
     38             "SELECT Score 
    " +
     39             "FROM InfoTable 
    " +
     40             "WHERE Name in (SELECT Name 
    " +
     41             "               FROM StatusTable 
    " +
     42             "               WHERE hasReview = '是');
    " +
     43             "这种方式非常方便,我们只要把查询条件写出来,剩下的操作都由mysql来处理。而在实际场景中,为了减少底层耦合,我们一般不通过mysql中的子查询方式联表查询,而是先执行子查询得到结果集,再以结果集作为条件执行外层查询。通常情况下,子查询和外层查询由上层的不同服务执行,这样就在一定程度上达到了底层数据库解耦的目的。注意这种实现方式将mysql内部的一部分复杂操作抛给了我们。这时,Mybatis中的foreach标签就有了用武之地。
    " +
     44             "
    " +
     45             "Mybatis 中foreach标签的用法
    " +
     46             "还以刚才的例子来说,先执行子查询
    " +
     47             "
    " +
     48             "SELECT Name FROM StatusTable WHERE hasReview = '是'
    " +
     49             "再执行外层查询,就是
    " +
     50             "
    " +
     51             "SELECT Score 
    " +
     52             "FROM InfoTable 
    " +
     53             "WHERE Name in ('张三' , '王五', '赵六', '周八');
    " +
     54             "也就是一个批量查询操作,将其抽象一下(假设有三个条件):
    " +
     55             "
    " +
     56             "SELECT * 
    " +
     57             "FROM <tableName> 
    " +
     58             "WHERE <ColumnName> IN (<case1>,<case2>,<case3>)
    " +
     59             "实际情况中,case可能远不止3个,这时可以在XXXMapper.xml文件中利用Mybatis中的foreach编写sql语句:
    " +
     60             "
    " +
     61             "SELECT * 
    " +
     62             "FROM <tableName> 
    " +
     63             "WHERE <ColumnName> IN 
    " +
     64             "<foreach collection="list" index="index" item="item" open="(" separator="," close=")">
    " +
     65             "    #{item}
    " +
     66             "</foreach>
    " +
     67             "就可以实现相同的效果了。
    " +
     68             "
    " +
     69             "那么问题来了,foreach标签中各种参数是什么含义呢?
    " +
     70             "
    " +
     71             "collection
    " +
     72             "如果传入的是单参数且参数类型是一个List的时候,collection属性值为list
    " +
     73             "如果传入的是单参数且参数类型是一个array数组的时候,collection的属性值为array
    " +
     74             "如果传入的参数是多个的时候,我们就需要把它们封装成一个Map了,当然单参数也可以封装成map,实际上如果你在传入参数的时候,在breast里面也是会把它封装成一个Map的,map的key就是参数名,所以这个时候collection属性值就是传入的List或array对象在自己封装的map里面的key
    " +
     75             "index 集合迭代位置
    " +
     76             "item 集合中的每一个元素别名
    " +
     77             "open 开始符号,例如这里的(,就对应于IN (<case1>,<case2>,<case3>)中IN后面的第一个(
    " +
     78             "separator 分隔符,例如这里的,,就对应于IN (<case1>,<case2>,<case3>)中的,
    " +
     79             "close 结束符号,例如这里的),就对应于IN (<case1>,<case2>,<case3>)中<case3>后面的)
    " +
     80             "参考
    ";
     81 
     82         String contentChars = baseContent;//每行的内容(字符流)
     83         byte[] contentBytes = baseContent.getBytes();//每行的内容(字节流)
     84 
     85         long begin = 0L;
     86         long end = 0L;
     87 
     88         //将时间统计写入文件Result.txt中
     89         FileWriter fileWriter = new FileWriter("./Result.txt", true);
     90         BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);
     91 
     92         System.out.println("Test FileOutputStream begin.");
     93         for (int lineNum = startlineNum; lineNum < maxlineNum; lineNum *= Multiplying) {
     94             begin = System.currentTimeMillis();
     95             testFileOutputStream(lineNum,contentBytes);
     96             end = System.currentTimeMillis();
     97             long timeElapse_FileOutputStream = end - begin;
     98             bufferedWriter.write(String.valueOf(timeElapse_FileOutputStream)+"	");
     99         }
    100         System.out.println("Test FileOutputStream end.
    ");
    101 
    102         System.out.println("Test BufferedOutputStream begin.");
    103         bufferedWriter.write("
    ");
    104         for (int lineNum = startlineNum; lineNum < maxlineNum; lineNum *= Multiplying) {
    105             begin = System.currentTimeMillis();
    106             testBufferedOutputStream(lineNum,contentBytes);
    107             end = System.currentTimeMillis();
    108             long timeElapse_BufferedOutputStream = end - begin;
    109             bufferedWriter.write(String.valueOf(timeElapse_BufferedOutputStream)+"	");
    110         }
    111         System.out.println("Test BufferedOutputStream end.
    ");
    112 
    113         System.out.println("Test FileWriter begin.");
    114         bufferedWriter.write("
    ");
    115         for (int lineNum = startlineNum; lineNum < maxlineNum; lineNum *= Multiplying) {
    116             begin = System.currentTimeMillis();
    117             testFileWriter(lineNum,contentChars);
    118             end = System.currentTimeMillis();
    119             long timeElapse_FileWriter = end - begin;
    120             bufferedWriter.write(String.valueOf(timeElapse_FileWriter)+"	");
    121         }
    122         System.out.println("Test FileWriter end.
    ");
    123 
    124         System.out.println("Test BufferedWriter begin.");
    125         bufferedWriter.write("
    ");
    126         for (int lineNum = startlineNum; lineNum < maxlineNum; lineNum *= Multiplying) {
    127             begin = System.currentTimeMillis();
    128             testBufferedWriter(lineNum,contentChars);
    129             end = System.currentTimeMillis();
    130             long timeElapse_BufferedWriter = end - begin;
    131             bufferedWriter.write(String.valueOf(timeElapse_BufferedWriter)+"	");
    132         }
    133         System.out.println("Test BufferedWriter end.
    ");
    134 
    135         System.out.println("Test NewOutputStream begin.");
    136         bufferedWriter.write("
    ");
    137         for (int lineNum = startlineNum; lineNum < maxlineNum; lineNum *= Multiplying) {
    138             begin = System.currentTimeMillis();
    139             testNewOutputStream(lineNum,contentBytes);
    140             end = System.currentTimeMillis();
    141             long timeElapse_NewOutputStream = end - begin;
    142             bufferedWriter.write(String.valueOf(timeElapse_NewOutputStream)+"	");
    143         }
    144         System.out.println("Test NewOutputStream end.
    ");
    145 
    146         System.out.println("Test NewBufferedWriter begin.");
    147         bufferedWriter.write("
    ");
    148         for (int lineNum = startlineNum; lineNum < maxlineNum; lineNum *= Multiplying) {
    149             begin = System.currentTimeMillis();
    150             testNewBufferedWriter(lineNum,contentChars);
    151             end = System.currentTimeMillis();
    152             long timeElapse_NewBufferedWriter = end - begin;
    153             bufferedWriter.write(String.valueOf(timeElapse_NewBufferedWriter)+"	");
    154         }
    155         System.out.println("Test NewOutputStream end.
    ");
    156 
    157         bufferedWriter.close();
    158     }
    159 
    160     /************************** I/O *****************************/
    161     //面向字节
    162     public static void testFileOutputStream (int lineNum, byte[] content) throws IOException {
    163         FileOutputStream fileOutputStream = new FileOutputStream(new File("./testFileOutputStream.txt"));
    164         while (--lineNum > 0) {
    165             fileOutputStream.write(content);
    166         }
    167         fileOutputStream.close();
    168     }
    169 
    170     public static void testBufferedOutputStream (int lineNum, byte[] content) throws IOException {
    171         FileOutputStream fileOutputStream = new FileOutputStream(new File("./testBufferedOutputStream.txt"));
    172         BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
    173         while (--lineNum > 0) {
    174             bufferedOutputStream.write(content);
    175         }
    176         bufferedOutputStream.close();
    177     }
    178 
    179     //面向字符
    180     public static void testFileWriter (int lineNum, String content) throws IOException {
    181         FileWriter fileWriter = new FileWriter("./testFileWriter.txt");
    182         while (--lineNum > 0) {
    183             fileWriter.write(content);
    184         }
    185         fileWriter.close();
    186     }
    187 
    188     public static void testBufferedWriter (int lineNum, String content) throws IOException {
    189         FileWriter fileWriter = new FileWriter("./testBufferedWriter.txt");
    190         BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);
    191         while (--lineNum > 0) {
    192             bufferedWriter.write(content);
    193         }
    194         bufferedWriter.close();
    195     }
    196 
    197 
    198     /************************** NIO ****************************/
    199     public static void testNewOutputStream (int lineNum, byte[] content) throws IOException {
    200         OutputStream outputStream = Files.newOutputStream(Paths.get("./testNewOutputStream.txt"));
    201         while (--lineNum > 0) {
    202             outputStream.write(content);
    203         }
    204         outputStream.close();
    205     }
    206 
    207     public static void testNewBufferedWriter (int lineNum,String content) throws IOException {
    208         BufferedWriter newBufferedReader = Files.newBufferedWriter(Paths.get("./testNewBufferedWriter.txt"));
    209         while (--lineNum > 0) {
    210             newBufferedReader.write(content);
    211         }
    212         newBufferedReader.close();
    213     }
    214 
    215 
    216     public static void main (String[] args) throws IOException {
    217         //多次测试时可清空result.txt文件
    218         FileWriter fileWriter = new FileWriter("./Result.txt");
    219         testDriver();
    220     }
    221 }
    View Code

    这次数据量就很大了,结果也就变了:

    所以,数据量很小的情况下,字符到字节的编码操作带来的性能降低几乎忽略不计;而数据量很大的时候,编码耗费的时间就很可观了。至于为什么在小数据量的情况下FileWriter快很多,目前我认为是一次操作两个字节所致(有了缓存之后就差不多了)。

    参考

    Java IO流学习总结

  • 相关阅读:
    20200318
    20200317
    Thinkphp 操作多个数据库
    base格式图片转文件存储
    Thinkphp POST 和 GET 传值
    Thinkphp调用微信扫一扫实例,学会再也不怕客户在微信提的奇葩要求了
    centos 安装ngnix mysql php
    PHP 区分微信、支付宝、QQ扫码
    PHP秒数计算时分秒
    Thinkphp 获取访问者的ip
  • 原文地址:https://www.cnblogs.com/xiaoxi666/p/9531893.html
Copyright © 2011-2022 走看看