IO流总结

随笔

学习Java很长时间了,也用过很多东西,但是基本都忘完了。比如IO流,用过很多次但还是有一点模糊。所以以后要经常总结。

我会以简单粗暴的方式记下使用IO流的方式,一些概念性的东西我基本不写,以后再百度吧,不然东西会很多,我以后可能看不下去。

 

正文

IO流分为字符流和字节流

  字符流大部分是用于一些文本的传输。比如:.txt   .xls等

  字节流大部分是用作图片或者是音频的传输。.jpg等

FileWriter    和 FileReader

  FileWriter是字符输出流,通常用于两个字节的字符操作

  FileReader是字符输入流,通常用于两个字节的字符操作

 

BufferedWriter   和 BufferedReader

 

  BufferedWriterFileWriter一样是字符输出流,不同的是BufferedWriter的效率要比FileWriter高的多,因为BufferedWriter有效的使用了缓存器,将缓存写满之后才输出到文件中。FileWriter每写一次数据,磁盘就有一个写操作,性能很差。BufferedWriter是用FileWriter作为parameter

 

  BufferedReader同理

FileOutputStream   和 FileInputStream

  FileOutputStream是字节输出流,通常用于图像等操作

  FileInputStream是字节输入流,通常用于图像等操作

 

BufferedInputStream   与 BufferedOutputStream

 

  BufferedInputSteam是带缓冲区的输入流,能够减少访问磁盘的次数,提高文件读取性能;

 

  BufferedOutputStream是带缓冲区的输出流,能够提高文件的写入效率。

 

InputStreamReader    和 OutputStreamWriter

 

  InputStreamReader是字符流Reader的子类,可以把字节流转化为字符流。InputStreamReader是用inputStream字节流来作为parameter参数的。编码方式可以用构造器指定。

 

  OutputStreamWriter是字符流Writer的子类,可以把字符流转化为字节流。OutputStreamWriter是用outputStream字节流来作为parameter参数的。

 

代码

测试FileWriter和FileReader 

 

a.txt是一个大约有36kb大小的文件,读取a.txt的数据写入b.txt循环一万次。每次都new新的FileReader和新的FileWriter。打印时间13:14:21.330 – 13:14:28.177。耗时6.847秒

 

FileReader fr = null;
FileWriter fw = null;
System.out.println(LocalDateTime.now());
for (int i=0;i<10000;i++) {
  fr = new FileReader("d:\\a.txt");
  fw = new FileWriter("d:\\b.txt");
  char[] c = new char[1024];
  while ((charInt = fr.read(c)) != -1) {
      fw.write(c, 0, charInt);
  }
  fw.write("第"+i+"次111111111111111111111111111111111111111111\n");
}
System.out.println(LocalDateTime.now());
fr.close();
fw.close();

 

测试BufferedWriter和BufferedReader

a.txt是一个大约有36kb大小的文件,读取a.txt的数据写入b.txt循环一万次 每次都new新的BufferedReader和新的BufferedWriter。打印时间13:08:18.665 – 13:08:18.905。耗时40毫秒

 

FileReader fr = new FileReader("d:\\a.txt");
FileWriter fw = new FileWriter("d:\\b.txt");
BufferedReader bfr = null;
BufferedWriter bfw = null;
System.out.println(LocalDateTime.now());
for (int i=0;i<10000;i++){
char[] c = new char[1024];
bfr = new BufferedReader(fr);
bfw = new BufferedWriter(fw);
while ((charInt = bfr.read(c))!=-1){
bfw.write(c,0, charInt);
}
bfw.write("第"+i+"次111111111111111111111111111111111111111111\n");
}
System.out.println(LocalDateTime.now());
fr.close();
bfr.close();
bfw.close();
fw.close();

BufferWriter和FileWriter都是字符输出流,但他们的速度相差太大了,前面概念也提到了因为BufferWriter利用缓存器的原理。

 

测试FileInputStream和FileOutputStream

接下来我用我之前遇到的一道面试题来记录这两个

题:一个文件夹里面有一万张图片,每隔五十张就取出一张放到另一个文件夹中

public static void main(String[] args) {
        File f = new File("D:\\FileLotsImg2");
        try {
            if (!f.exists()){
                f.mkdir();
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        LinkedList<File> files = traverseFolder1("D:\\FileLotsImg");//这是放一万张图片的文件夹路径
        int byteread = 0;//读取的位数
        FileInputStream in = null;
        FileOutputStream ou = null;
        for (File file : files){
            String imgName = file.getPath().substring(file.getPath().lastIndexOf("\\"));
            File copyImg = new File(f.getPath()+imgName);
            System.out.println(imgName+"11111111111111111111");
            try {
                in = new FileInputStream(file);
                ou = new FileOutputStream(copyImg);
                byte[] buffer = new byte[10240];
                while ((byteread = in.read(buffer)) != -1) {
                //将读取的字节写入输出流
                    ou.write(buffer, 0, byteread);
                }
            }catch (IOException e){
                e.printStackTrace();
            }
        }
        try {
            if (in != null){
                in.close();;
            }
            if (ou != null){
                ou.close();
            }
        }catch (IOException e){
            e.printStackTrace();
        }
    }

    public static LinkedList<File> traverseFolder1(String path){
        LinkedList<File> list = new LinkedList();
        Integer i = 0;
        File file = new File(path);
        if (file.exists()){
            File[] files = file.listFiles();
            for (File file1:files){
                i++;
                if (i == 50){
                    list.add(file1);
                    System.out.println("已添加到集合");
                }else if (i>=51){
                    i=1;
                    System.out.println("第"+i+"张图片:"+file1.getAbsolutePath());
                }else {
                    System.out.println("第"+i+"张图片:"+file1.getAbsolutePath());
                }
            }
        }
        return list;
    }

 

接下来说一下InputStreamReaderOutputStreamWriter,既然这两个是把字节流转化为字符流,那么能不能把图片转成字符流输入然后再转化为字节流输出呢?这样能不能大大节省效率呢?答案是:不能,亲测无用;只要是Reader和Writer都是跟字符有关的

 

  BufferedInputStreamBufferedOutputStream和上面同理,也是提高了性能

  InputStreamReader和OutputStreamWriter的具体功能就是字符流和字节流相互间的转换,并且在转换的过程中还可以自定义字符的编码格式。所以就算是效率不高并且不能传输图片,但是肯定有用的到的地方

  a.txt是一个大约有36kb大小的文件,读取a.txt的数据写入b.txt循环一万次 每次都new新的InputStreamReader和新的OutputStreamWriter。打印时间14:20:13.712 – 14:20:13.962。耗时250毫秒

File file = new File("d:\\a.txt");
        File fill = new File("d:\\b.txt");
        int byteRead = 0;//读取的位数
        FileInputStream in = new FileInputStream(file);
        FileOutputStream ou = new FileOutputStream(fill);
        InputStreamReader inStr = null;
        OutputStreamWriter outStr = null;
        char[] c = new char[1024];
        System.out.println(LocalDateTime.now());
        for (int i=0;i<10000;i++){
            inStr = new InputStreamReader(in);
            outStr = new OutputStreamWriter(ou,"UTF-8");
            while ((byteRead = inStr.read(c)) != -1) {
                outStr.write(c);
            }
            outStr.write("第"+i+"次111111111111111111111111111111111111111111\n");
        }
        System.out.println(LocalDateTime.now());
        inStr.close();
        outStr.close();
        in.close();
        ou.close();

 

好了,到这里我的总结就算是结束了,有好的干货务必留言一下,跪谢

 

点赞