IO流(上)

173 阅读6分钟

IO流:数据的输入输出问题

image.png

image.png

File类的使用

image.png

image.png

image.png

File类的使用

1.File类的对象,代表一个文件或一个文件目录(俗称:文件夹)
2.File类声明在java.io包下
 */
public class FileTest {
    /*
    1.如何创建File类的实例
        1.File(String filePath)
        2.File(String parentPath,String childPath)
        3.File(File parentFile,String childPath)
    2.相对路径:相较于某个路径下,指明的路径
      绝对路径:包含盘符在内的文件或文件目录的路径
    3.路径分隔符:
        windows:\\
        unix:/
     */
    @Test
    public void test(){
        //构造器1:File(String filePath)
        File file = new File("hello.txt");//相对于当前这个module,相对路径
        File file1 = new File("E:\\MYjava\\IO\\hi.txt");
        System.out.println(file);//hello.txt
        System.out.println(file1);//E:\MYjava\IO\hi.txt

        //构造器2:File(String parentPath,String childPath)
        File file2 = new File("E:\\MYjava","IO");
        System.out.println(file2);//E:\MYjava\IO

        //构造器3:
        File file3 = new File(file2,"he.txt");
        System.out.println(file3);//E:\MYjava\IO\he.txt

File类的常用方法

image.png file1.renameTo(file2):要想返回true,需要file1存在,file2不存在

image.png

image.png

IO流原理及流的分类

image.png

  • 按操作数据单位不同分类为:字节流(8bit),字符流(16bit)
  • 按数据的流向不同分为:输入流,输出流
  • 按流的角色分为:节点流,处理流

image.png

image.png

image.png

一.流的分类:
1.按操作数据单位不同分类为:字节流(8bit)(InputStream,OutputStream),字符流(16bit)(Reader,Writer)
2.按数据的流向不同分为:输入流,输出流
3.按流的角色分为:节点流,处理流
二.流的体系结构
抽象基类            节点流(文件流)         缓冲流(处理流的一种)
InputStream    	 FileInputStream     BufferInputStream         
OutputStream      FileOutputStream    BufferOutputStream        
Reader      FileReader(read(char[]cbuf))    BufferReader         
Writer  FileWriter(write(char[]cbuf,0,len)) BufferWriter     
 */
public class IOTest {
    //将IO下的hello.txt文件内容读入程序中,并输出到控制台
    //说明点:
    //1.read()的理解:返回读入的一个字符。如果达到文件末尾,返回-1
    //2.异常的处理:为了保证流资源一定可以执行关闭操作。需要使用try-catch-finally处理
    //3.读入的文件一定要存在,否则就会报FileNotFoundException
    @Test
    public void test(){
        FileReader fr = null;
        try {
            //1.实例化File类的对象,指明要操作的文件
            File file = new File("hello.txt");//相对路径,相较于当前module
            //2.提供具体的流
            fr = new FileReader(file);
            //3.数据的读入
            //read():返回读入的一个字符,如果达到文件末尾,返回-1
            //方式1:
//        int data = fr.read();
//        while (data!=-1){
//            System.out.print((char) data);
//            data=fr.read();
//        }
            //方式2:语法上针对方式1的修改
            int data;
            while ((data=fr.read())!=-1){
                System.out.print((char) data);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
            //4.流的关闭操作
                if(fr!=null) {
                    fr.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        
//读数据的操作
//对read操作升级:使用read的重载方法
    @Test
    public void test1(){
        FileReader fr = null;
        try {
            //1.File类的实例化
            File file = new File("hello.txt");
            //2.FileReader流的实例化
            fr = new FileReader(file);
            //3.读入的操作
            //read(char[] cbuffer):返回每次读入cbuffer数组的字符的个数。如果达到文件末尾,返回-1
            char[] cbuffer = new char[5];
            int len;
            while ((len=fr.read(cbuffer))!=-1){
                //方式1:
                //错误的写法:
//                for(int i = 0;i<cbuffer.length;i++){
//                    System.out.print(cbuffer[i]);//出来helloworld123ld,
//                    因为length=5,而在遍历最后一个数组中时只有1,2,3。
                    //最后两个位置没有替换,还是ld
//                }正确的写法
//                for (int i = 0;i < len;i++){
//                    System.out.print(cbuffer[i]);
//                }
                //方式2:
                //错误的写法:与方式1错的一样
//                String str = new String(cbuffer);
//                System.out.println(str);
                //正确的写法:
                String str = new String(cbuffer,0,len);
                System.out.print(str);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if(fr!=null) {
                    //4.资源的关闭
                    fr.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }

写数据的操作

//从内存中写数据到硬盘文件里

//说明:1.输出操作,对应的File可以不存在,并不会报异常
//      2.File对应的硬盘的文件如果不存在,在输出的过程中,会自动创建此文件
//        File对应的硬盘的文件如果存在:
    //          如果流使用的构造器是:FileWriter(file,false)/FileWriter(file):对原有文件进行覆盖
//              如果流使用的构造器是:FileWriter(file,true):不会对原有文件进行覆盖,而是在原有内容基础上追加内容
public void test4() throws IOException {
    //1.提供File类的对象,指明写出到的文件
    File file = new File("hello1.txt");

    //2.提供FileWriter的对象,用于数据的写出
    FileWriter fw = new FileWriter(file);

    //3.写出的操作
    fw.write("I hava a dream");
    fw.write("you need to have a dream");

    //4.流资源的关闭
    fw.close();

使用FileReader和FileWriter实现文本文件的复制

public void test5(){
    FileReader fr = null;
    FileWriter fw = null;
    try {
        //1.创建File类的对象,指明读入和写出的文件
        File srcFile = new File("hello.txt");
        File destFile = new File("hello2.txt");

        //2.创建输入流和输出流的对象
        fr = new FileReader(srcFile);
        fw = new FileWriter(destFile);

        //3.数据的读入和写出操作
        char[]cbuf = new char[5];
        int len;//记录每次读入到cbuf数组中的字符的个数
        while ((len=fr.read(cbuf))!=-1){
            //每次写出len个字符
            fw.write(cbuf,0,len);
        }
    } catch (IOException e) {
        e.printStackTrace();
    } finally {//4.关闭流资源
        if(fw!=null) {
            try {
                fw.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if(fr!=null) {
            try {
                fr.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

字符流不能处理图片等字节文件

/*测试FileInputStream和FileOutputStream的作用
1.对于文本文件(txt,java,c,cpp),使用字符流处理
2.对于非文本文件(jpg,mp3,mp4,avi,doc,ppt...),使用字节流处理

 */

public class FileInputOutputTest {
    //使用字节流FileInputStream处理文本文件,可能出现乱码
    @Test
    public void test(){
        FileInputStream fis = null;
        try {
            //1.造文件
            File file = new File("hello.txt");

            //2.造流
            fis = new FileInputStream(file);

            //3.读数据
            byte[]buffer = new byte[5];
            int len;//记录每次读取的字节的个数
            while ((len=fis.read(buffer))!=-1){
                String str = new String(buffer,0,len);
                System.out.print(str);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {//4.关闭资源
            if(fis!=null){
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }



    }//实现对图片的复制
    @Test
    public void test1(){
        FileInputStream fis = null;
        FileOutputStream fos = null;
        try {
            //1.造文件
            File scrFile = new File("小哀.jpg");
            File destFile = new File("小哀1.jpg");

            //2.造流
            fis = new FileInputStream(scrFile);
            fos = new FileOutputStream(destFile);

            //3.读数据
            byte[]buffer = new byte[5];
            int len;//记录每次读取的字节的个数
            while ((len=fis.read(buffer))!=-1){
                fos.write(buffer,0,len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {//4.关闭资源
            if(fis!=null){
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(fos!=null){
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
//指定路径下文件的复制
public void copyFile(String srcPath,String destPath){
    FileInputStream fis = null;
    FileOutputStream fos = null;
    try {
        //1.造文件
        File scrFile = new File(srcPath);
        File destFile = new File(destPath);

        //2.造流
        fis = new FileInputStream(scrFile);
        fos = new FileOutputStream(destFile);

        //3.读数据
        byte[]buffer = new byte[5];
        int len;//记录每次读取的字节的个数
        while ((len=fis.read(buffer))!=-1){
            fos.write(buffer,0,len);
        }
    } catch (IOException e) {
        e.printStackTrace();
    } finally {//4.关闭资源
        if(fis!=null){
            try {
                fis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if(fos!=null){
            try {
                fos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
@Test
public void test6(){
    long l = System.currentTimeMillis();
    copyFile("小哀.jpg","小哀2.jpg");
    long l1 = System.currentTimeMillis();
    System.out.println("复制操作花费的时间为"+(l1-l));
}

缓冲流的使用

/*处理流之一:缓冲流的使用
1.缓冲流:
BufferInputStream
BufferOutputStream
BufferReader
BufferWriter
2.作用:提高流的读取,写入的速度
原因:内部提供了一个缓冲区
3.处理流,就是"套接"在已有的流的基础上
 */
public class BufferedTest {

    //使用非文本文件的复制
    @Test
    public void test() throws IOException {

        //1.造文件
        File srcFile = new File("小哀.jpg");
        File destFile = new File("小哀.jpg");
        //2.造流
        //2.1 造节点流
        FileInputStream fis = new FileInputStream(srcFile);
        FileOutputStream fos = new FileOutputStream(destFile);
        //2.2 造缓冲流
        BufferedInputStream bis = new BufferedInputStream(fis);
        BufferedOutputStream bos = new BufferedOutputStream(fos);
        //3.复制的细节:读取,写入
        byte[]buffer = new byte[10];
        int len;
        while ((len=bis.read(buffer))!=-1){
            bos.write(buffer,0,len);
        }
        //4.资源关闭
        //要求:先关闭外层的流,再关闭内层的流
        bos.close();
        bis.close();
        //说明:关闭外层时内层时也会自动进行关闭

用上缓冲流速度将会很快!

BufferedReader与BufferedWriter与上述类似