IO流的回顾学习

x33g5p2x  于2022-02-07 转载在 其他  
字(8.2k)|赞(0)|评价(0)|浏览(363)

首先说一下最近遇到了关于用户头像上传的问题,然后发现自己的IO流已经忘得差不多了~~~~现在来回顾一下!

首先说一下IO流的分类

  • ①根据操作的数据类型的不同可以分为 :字节流与字符流

  • ②根据数据的流向分为:输入流与输出流,程序(内存)作为参照物,程序从外部读取称为输入(Input),程序向外部写数据成为输出(Output)。

一:字节输入流:父类:InputStream

常用的字节输入流:FileInputStream

(1):.FileInputStream

①构造方法:

  • FileInputStream(File)
  • FileInputStream(String filename)

常用方法:

1:read :读取一个字节,返回该字节的值,如果到达文件的末尾,则返回-1。需要注意:read()方法和迭代器一样,会自动下移的
2:read(byte[ ])从输入流中读取至多一个数组长度的内容,到达文件末尾,则返回-1。
3:available()没有读取的剩余字节数,如果该文件还从未被读取,就返回该文件的长度。
4:close() 关闭流并释放资源

字节输入流代码演示:

1:字节输入流的读取不使用byte数组读取)

其中1.txt位于本项目的根目录下:内容为"ftzlovedsj"
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

public class Demo6 {

    public static void main(String[] args) throws IOException{
        File file=new File("1.txt");     //新建一个文件的抽象路径
        FileInputStream fis=new FileInputStream(file);
        int result=fis.read();
        System.out.println(result);

    }

}

程序执行的结果为102,因为读取的f的ASCII码值

字节输入流的循环读取:

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class Test1 {

    public static void main(String[] args) throws IOException {
        File file = new File("E:\\浏览器下载资料\\IOreview\\file\\1.txt");
        FileInputStream fis = new FileInputStream(file);

        // 单个读取
        int result = fis.read();
        System.out.println(result);

        int res;
        //循环读取
        while ((res=fis.read())!=-1){
            System.out.print(res+"\t");
        }

    }
}

2:字节输入流的读取·使用byte数组逐行读取!):(方法父类同上)

这里也是属于字节输入流的!和上面的区别就是多了一个 byte[] bt = new byte[1024]; //数组,增加了这个的功能就是可以逐行读取!并且效率更高!

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class Test2 {

    /**
     * 字符输入流
     * @param args
     */

    public static void main(String[] args) throws IOException {
        File file = new File("E:\\浏览器下载资料\\IOreview\\file\\2.txt");
        FileInputStream fis = new FileInputStream(file);
        byte[] bt = new byte[1024];  //数组
        int count;
        while ((count=fis.read(bt))!=-1){
            String str = new String(bt,0,count);
            System.out.println(str);
        }
    }
}

比较一下单纯字节流和按行读(byte)字节流的读取速度:

字节输入流:

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class Test3 {

    public static void main(String[] args) throws IOException {

        File file = new File("E:\\浏览器下载资料\\IOreview\\file\\3.jpg");
        FileInputStream fis = new FileInputStream(file);
        int count;
        Long start = System.currentTimeMillis();
        while ((count=fis.read())!=-1){
            System.out.println(count);

        }
        System.out.println("=========下面是所需时间============");
        Long end = System.currentTimeMillis();
        System.out.println(end-start);

    }
}

按行读(byte)字节输入流:

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class Test4 {

    /**
     * 字符输入流速度
     * @param args
     */

    public static void main(String[] args) throws IOException {
        File file = new File("E:\\浏览器下载资料\\IOreview\\file\\3.jpg");
        FileInputStream fis = new FileInputStream(file);
        byte[] bt = new  byte[1024];
        int count;
        long start=System.currentTimeMillis();
        while ((count=fis.read(bt))!=-1){
            System.out.println(count);
        }
        long end=System.currentTimeMillis();
        System.out.println("======下面是所用的时间======");
        System.out.println(end-start);

    }
}

明显这加上byte[1024]字节流快的不是一点点啊!,因为加上后他就成了整块读取!

总结:字节输入流,不加byte[1024]这个就是一口气全读出来输出,加上的话就是按行读并且速度更快!

二:字节输出流:

1:字节输出流:OutputStream 是所有输出流的超类(所有父类,类同于上面的InputStrem)

2:常用子类:FileOutputStream 文件字节输出流

3.1:构造方法:FileOutputStream(File file) /FileOutputStream(String name)

注意:如果父目录不存在,会报FileNotFoundException异常,如果父目录存在,会创建一个新的文件,如果此时已经有文件存在,会覆盖原文件

3.2:  FileOutputStream(File file,boolean flag)/FileOutputStream(String name,boolean flag)

注意:如果当前文件需要从文件末尾进行插入(接着文件里的内容继续写),必须将第二个参数设置为true,默认不写为false,会覆盖原文件

4:常用方法:

  • write(int)向文件中写入一个字节的值

  • write(byte[]) 向文件中写入一个数组的数据。

  • write(byte[] offset len) 将 偏移量为 offset 的索引位置的长度为 len 的数据,写入到输出流中。

5:示例:

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class Test5 {
    /**
     * 字节输出流
     * @param args
     */

    public static void main(String[] args) throws IOException {
        File file = new File("E:\\浏览器下载资料\\IOreview\\file\\3.txt");
        FileOutputStream fos = new FileOutputStream(file);
        fos.write("我要和佳佳永远在一起哦!".getBytes());
        System.out.println("写入成功!");

    }
}

自动生成了这样的一个文件!里面写了这样的内容

字节输出流:(文件的复制–覆盖)

import java.io.*;

public class Test6 {

    /**
     * 字符输出流复制文件
     * @param args
     * @throws FileNotFoundException
     */
    public static void main(String[] args) throws IOException {
        File file = new File("E:\\浏览器下载资料\\IOreview\\file\\2.txt");
        FileInputStream fis = new FileInputStream(file);
        FileOutputStream fos = new FileOutputStream(new File("E:\\浏览器下载资料\\IOreview\\file\\3.txt"));
        byte[] bt = new byte[1024];
        int count;
        while ((count=fis.read(bt))!=-1){
          fos.write(bt,0,count);
        }
        System.out.println("复制成功");
        fis.close();
        fos.close();

    }
}

字节输出流:(文件的不覆盖–增添)加上一个true:

import java.io.*;

public class Test7 {

    public static void main(String[] args) throws IOException {

        File file = new File("E:\\浏览器下载资料\\IOreview\\file\\2.txt");
        FileInputStream fis = new FileInputStream(file);
        FileOutputStream fos = new FileOutputStream(new File("E:\\浏览器下载资料\\IOreview\\file\\3.txt"),true);
        byte[] bt = new byte[1024];
        int count;
        while ((count=fis.read(bt))!=-1){
            fos.write(bt,0,count);
        }
        System.out.println("复制成功");
        fis.close();
        fos.close();
        
    }
}

我是分割线----------------------------------------------------------------------------

我是分割线----------------------------------------------------------------------------

我是分割线----------------------------------------------------------------------------

三:字符输入流:

1:字符输入流:父类:Reader

字符流:就是在字节流的基础上,加上编码,形成的数据流,因为字节流在操作字符时,可能会有中文导致的乱码,所以由字节流引申出了字符流

2:常用子类:FileReader

3:常用方法:

  • read();

  • read(char[ ]);

  • read(char[ ] ,offset,len);

示例:

import java.io.File;
import java.io.FileReader;
import java.io.IOException;

public class Test9 {

    /**
     * 字符输入流
     */
    public static void main(String[] args) throws IOException {
        File file = new File("E:\\浏览器下载资料\\IOreview\\file\\2.txt");
        FileReader fr = new FileReader(file);
        char[] ca = new char[1024];
        //单个读取
        int result = fr.read();
        System.out.println("单个读取"+result);

        // 循环读取
        int res;
        System.out.println("循环读取");
        while ((res=fr.read(ca))!=-1){
            String str = new String(ca,0,res);
            System.out.println(str);
            System.out.println(res+"\t");
        }

    }
}

在这里其实体现不出什么来,字符输入流和字节输入流,唯一的一个差距就是,在逐行读取方面,字节输入流是加了byte[1024],字符输入流是加了char[1024]。然后速度的话家人们自己测一次哦,和上面对称的步骤!

四:字符输出流:父类:Writer

1:常用子类:文件字符输出流: Filewriter

2:文件字符输出常用方法:

  • writer();

  • writer(char[ ]);

  • writer(char[ ],offset,len);

  • writer(string);

  • flush()刷新缓冲区

注意:close()方法默认调用了flush()方法,但是flush()方法只刷新缓冲区,而close()还会关闭IO流

示例:

import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class Test10 {
    /**
     * 字符输出流
     */

    public static void main(String[] args) throws IOException {

        File file = new File("E:\\浏览器下载资料\\IOreview\\file\\2.txt");
        FileReader fr = new FileReader(file);
        FileWriter fw = new FileWriter(new File("E:\\浏览器下载资料\\IOreview\\file\\4.txt"));
        char[] chars = new char[1024];
        int count;
        while ((count=fr.read(chars))!=-1){
            fw.write(chars,0,count);
        }
        System.out.println("字符输出流复制成功");
        fr.close();
        fw.close();
        
    }

}

分割线================================================

分割线================================================

分割线================================================

缓存流!

1:带缓存的字符流:BufferedReader/BufferedWriter 带缓冲区的字符输入流与字符输出流。

2:带缓冲区的字符输入流:BufferedReader:常用方法:readLine() 读取一行,如果为文件末尾,返回值为null。

带缓冲区的字符输出流:BufferedWriter:常用方法:writer(string)将字符串写入 到输出流。 newLine()根据系统的行分割符进行换行。

BufferReader代码示例:

其实字符缓冲输入流和上面的字符输入流就是多了一个缓冲,也就是多了一个 BufferedReader br = new BufferedReader(fr);,前面的两句是一模一样的!

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;

public class Test11 {

    /**
     * 字符缓冲输入流
     */

    public static void main(String[] args) throws IOException {
        File file = new File("E:\\浏览器下载资料\\IOreview\\file\\2.txt");
        FileReader fr = new FileReader(file);
        BufferedReader br = new BufferedReader(fr);
        String str;
        while ((str=br.readLine())!=null){
            System.out.println(str);
        }
        br.close();

    }
}

BufferedWriter代码示例:

import java.io.*;

public class Test12 {
    /**
     * 字符缓冲输出流
     */

    public static void main(String[] args) throws IOException {
        File file = new File("E:\\浏览器下载资料\\IOreview\\file\\2.txt");

        FileReader fr = new FileReader(file);
        BufferedReader br = new BufferedReader(fr);

        FileWriter fw = new FileWriter(new File("E:\\浏览器下载资料\\IOreview\\file\\5.txt"));
        BufferedWriter bw = new BufferedWriter(fw);
        char[] chars = new char[1024];
        int count;
        while ((count=br.read(chars))!=-1){
            bw.write(chars,0,count);
        }
        System.out.println("字符·缓冲输出流复制成功");
        bw.close();
        br.close();
        
    }
}

总结:

1:缓冲流就是在字符流的基础上加了一个Buffer!

2:使用字节流的传输的文件,不一定能使用字符流传输,使用字符流传输的文件都可以转成字节流在进行传输

3:我们拷贝的文件不确定只包含字符流,有可能包含字节流(图片,视频,音乐)。考虑到通用性,所以要使用字节流。

相关文章

目录