Java IO流

目录

异常概述

什么是异常?

异常的分类(Throwable)

异常(Exception)

错误(Error)

JVM默认的异常处理方式

开发中异常的处理方式

try…catch(finally):捕获,自己处理

throws:抛出,交给调用者处理

异常处理的注意事项

多个异常分别处理:

 finally代码块:

方法重写:

IO流概述

什么是IO流?

IO流能干什么?

IO流的分类

按数据流向分:

按操作方式分:

IO流体系

字符流:按字符读写数据的IO流

字节流:按字节读写数据的IO流

File类

概念

构造方法:

成员方法:

字符流读写文件

字符流读数据 – 按单个字符读取

字符流读数据 – 按字符数组读取

字符流写数据 – 按单个字符写入

字符流写数据 – 按字符数组写入

字符流写数据 – 按字符数组写入 

字符流拷贝文件 – 按单个字符读写

字符流拷贝文件 – 按字符数组读写

字符缓冲流拷贝文件的标准代码 

 字符缓冲流普通用法

 字符缓冲流一次读写一行

字节流读写文件

字节流拷贝文件 – 按单个字节读写

字节流拷贝文件 – 按字节数组读写

字节缓冲流拷贝文件的标准代码

案例:模拟文件上传功能

需求:使用控制台模拟实际开发中上传用户头像的功能

 完整代码


异常概述

什么是异常?

即非正常情况,通俗地说,异常就是程序出现的错误

异常的分类(Throwable)

异常(Exception)

合理的应用程序可能需要捕获的问题    举例:NullPointerException

错误(Error)

合理的应用程序不应该试图捕获的问题     举例:StackOverFlowError 异常的处理方式

JVM默认的异常处理方式

在控制台打印错误信息,并终止程序  

开发中异常的处理方式

try…catch(finally):捕获,自己处理

try {
// 尝试执行的代码
} catch(Exception e) {
// 出现可能的异常之后的处理代码
} finally {
// 一定会执行的代码,如关闭资源
}
package com.itcast.demo11;

public class Test {
    public static void main(String[] args) {
        try {
            int a = 10/10;
            System.out.println(a);
        }catch (Exception e){
            System.out.println("被除数不能为0");
        }finally {
            System.out.println("加不加都一样");
        }
        System.out.println("这句话执行了吗");
    }
}

throws:抛出,交给调用者处理

public void 方法名() throws Exceptoin {
}
package com.itcast.demo11;

public class Test1 {
    public static void main(String[] args) throws Exception {
        //show()方法把异常抛出了,调用者需要处理
        //1.接着抛异常
//        show();
//        System.out.println("执行了吗");
        //2.try.catch处理
        try {
            show();
        } catch (Exception e) {
            System.out.println("代码出问题了");
        }
        System.out.println("执行了吗");
    }

    public static void show() throws Exception {
        int a = 10 / 0;
        System.out.println(a);
    }
}

异常处理的注意事项

多个异常分别处理:

try {
// 尝试执行的代码
} catch(异常A e) {
// 出现可能的异常之后的处理代码
} catch(异常B e) {
// 出现可能的异常之后的处理代码
} finally {
// 一定会执行的代码,如关闭资源
}

 finally代码块:

可以省略(不能和catch部分同时省略) finally代码之前若有return语句,先执行return语句,再执行finally代码 块,最后返回return的结果

方法重写:

子类方法不能比父类方法抛出更大的异常

IO流概述

什么是IO流?

I/O,即输入(Input)输出(Output),IO流指的是数据像连绵的流体一样进行传输。

IO流能干什么?

在本地磁盘或网络上传输(读/写)数据

IO流的分类

按数据流向分:

输入流

输出流

按操作方式分:

字节流:

  • InputStream
  • OutputStream

字符流:

  • Reader
  • Writer

IO流体系

字符流:按字符读写数据的IO流

Reader

  • FileReader(普通)
  • BufferedFileReader(高效)

Writer

  • FileWriter(普通)
  • BufferedFileReader(高效)

字节流:按字节读写数据的IO流

InputStream

  • FileInputStream(普通)
  • BufferedInputStream(高效)

OutputStream

  • FileOutputStream(普通)
  • BufferedOutputStream(高效)

File类

概念

文件,文件夹,一个File对象代表磁盘上的某个文件或文件夹

构造方法:

File(String pathname)

File(String parent, String child)

File(File parent, String child)

成员方法:

createNewFile():创建文件

mkdir()和mkdirs():创建目录

isDirectory():判断File对象是否为目录

isFile():判断File对象是否为文件

exists():判断File对象是否存在

package com.itcast.demo11;

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

public class Test2 {
    public static void main(String[] args) throws IOException {
        //方式一 根据字符串形式的路径获取File对象
        File file1 = new File("D:\\2021.3.1\\java\\1.txt");
        System.out.println("file1:" + file1);
        //方式二 根据字符串形式的父目录以及子目录创建File对象
        File file2 = new File("D:\\2021.3.1\\java", "1.txt");
        System.out.println("file2:" + file2);
        //方式三 根据父目录对象,以及字符串形式的子目录来获取File对象
        File file3 = new File("D:\\2021.3.1\\java");
        File file4 = new File(file3, "1.txt");
        System.out.println("file4:" + file4);

        //创建功能
        File file5 = new File("D:\\2021.3.1\\java\\2.txt");
        boolean flag1 = file5.createNewFile();
        System.out.println(flag1);

        //创建文件夹
        File file6 = new File("D:\\2021.3.1\\java\\a");
        boolean flag2 = file6.mkdir();
        System.out.println(flag2);

        //多级目录
        File file7 = new File("D:\\2021.3.1\\java\\a\\b\\c");
        boolean flag3 = file7.mkdirs();
        System.out.println(flag3);

        //判断功能
        File file8 = new File("D:\\2021.3.1\\java\\a\\b");
        System.out.println("测试file8是否为文件夹:" + file8.isDirectory());
        System.out.println("测试file8是否为文件:" + file8.isFile());
        System.out.println("测试file8是否存在:" + file8.exists());
    }
}

getAbsolutePath():获取文件的绝对路径

        从本地磁盘开始的路径

        举例:C:\Users\itcast\Desktop

getPath():获取文件的相对路径

        相对某一位置的路径

        Java项目中,相对路径从项目名开始

getName():获取文件名

list():获取指定目录下所有文件(夹)名称数组

listFiles():获取指定目录下所有文件(夹)File数组

package com.itcast.demo11;

import java.io.File;

public class Test3 {
    public static void main(String[] args) {
        File file1 = new File("lib/1.txt");
        //绝对路径
        String path1 = file1.getAbsolutePath();
        System.out.println(path1);
        //相对路径
        String path2 = file1.getPath();
        System.out.println(path2);

        //获取文件名
        String file1Name = file1.getName();
        System.out.println(file1Name);

        //获取lib文件夹下所有的文件,文件夹,名称数组String[]
        File file2 = new File("lib");
        String[] list = file2.list();
        for (String name : list) {
            System.out.println(name);
        }

        File[] files = file2.listFiles();
        for (File file : files) {
            System.out.println(file);
        }
    }
}

字符流读写文件

字符流读数据 – 按单个字符读取

创建字符流读文件对象:

Reader reader = new FileReader("readme.txt");

调用方法读取数据:

int data = reader.read();

读取一个字符,返回该字符代表的整数,若到达流的末尾,返回-1

异常处理:

throws IOException
package com.itcast.demo11;

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;

public class Test4 {
    public static void main(String[] args) throws IOException {
        //创建字符输入流对象
        Reader reader = new FileReader("lib/1.txt");
        //读取数据
//        int ch1 = reader.read();
//        System.out.println(ch1);
//        int ch2 = reader.read();
//        System.out.println(ch2);
//        int ch3 = reader.read();
//        System.out.println(ch3);
//        int ch4 = reader.read();
//        System.out.println(ch4);
        //优化
        int ch;     //接受读取到的字符
        /*
        (ch = reader.read()) != -1
            1.执行reader.read()读取一个字符
            2.将读取到的字符赋值给变量
            3.用读取到的字符与-1比较
         */
        while ((ch = reader.read()) != -1) {
            //ch = reader.read();
            System.out.println(ch);
        }
        //释放资源
        reader.close();
    }
}

字符流读数据 – 按字符数组读取

创建字符流读文件对象:

Reader reader = new FileReader("readme.txt");

调用方法读取数据:

// 读取字符到数组中,返回读取的字符数,若到达流的末尾,返回-1
char[] chs = new char[2048];
int len = r.read(chs);

异常处理:

throws IOException
package com.itcast.demo11;

import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;

public class Test5 {
    public static void main(String[] args) throws IOException {
        Reader reader = new FileReader("lib/2.txt");

//        char[] chs = new char[3];
//        int len1 = reader.read(chs);
//        System.out.println(chs);    //abc
//        System.out.println(len1);   //3
//
//        int len2 = reader.read(chs);
//        System.out.println(chs);    //def
//        System.out.println(len2);   //3
//
//        int len3 = reader.read(chs);
//        System.out.println(chs);    //gef
//        System.out.println(len3);   //1
//
//        int len4 = reader.read(chs);
//        System.out.println(chs);    //gef
//        System.out.println(len4);   //-1

        //优化
        char[] chars = new char[3];
        int len;
        while ((len = reader.read(chars)) != -1) {
            //chars:要操作的数组 0:起始索引 len:要操作字符的个数
            String s = new String(chars, 0, len);
            System.out.println(s);
        }

        reader.close();
    }
}

字符流写数据 – 按单个字符写入

创建字符流写文件对象:

Writer writer = new FileWriter("dest.txt");

调用方法写入数据:

int x = '中';
writer.write(x); // 写一个字符

异常处理:

throws IOException

字符流写数据 – 按字符数组写入

创建字符流写文件对象:

Writer writer = new FileWriter("dest.txt");

调用方法写入数据(写入字符数组):

char[] chs = {'橙', '心', '橙', '意'};
writer.write(chs); // 写一个字符数组

异常处理: 

throws IOException

字符流写数据 – 按字符数组写入 

创建字符流写文件对象:

Writer writer = new FileWriter("dest.txt");

调用方法写入数据(写入字符串):

writer.write("小黑爱学习"); // 写入一个字符串

异常处理:

throws IOException
package com.itcast.demo11;

import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;

public class Test6 {
    public static void main(String[] args) throws IOException {
        //创建字符输出流
        Writer writer = new FileWriter("lib/1.txt");

        //一次写一个字符
        writer.write("ok");
        //一次写一个指定的字符数组
        char[] chars = {'今', '天', '星', '期', '一'};
        writer.write(chars, 2, 3);
        //一次写一个字符串
        writer.write("今天开心");
        
        writer.close();

    }
}

字符流拷贝文件 – 按单个字符读写

 

创建字符流读文件对象:

Reader reader = new FileReader("readme.txt");

创建字符流写文件对象:

Writer writer = new FileWriter("dest.txt");

调用方法读取数据:

int data = reader.read();

调用方法写入数据:

writer.write(data);

异常处理:

 throws IOException

关闭资源:

 finally { 
reader.close(); 
writer.close(); 
}
package com.itcast.demo11;

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

public class CopyFile {
    public static void main(String[] args) throws IOException {
        FileReader fr = new FileReader("lib/1.txt");
        FileWriter fw = new FileWriter("lib/2.txt");
        int len;
        while ((len = fr.read()) != -1) {
            fw.write(len);
        }
        fr.close();
        fw.close();
    }
}

字符流拷贝文件 – 按字符数组读写

创建字符流读文件对象:

Reader reader = new FileReader("readme.txt");

创建字符流写文件对象:

Writer writer = new FileWriter("dest.txt");

调用方法读取数据:

char[] chs = new char[2048];

int len = reader.read(chs);

调用方法写入数据:

writer.write(chs, 0, len)

异常处理:

throws IOException

关闭资源:

finally {
reader.close();
writer.close();
}
package com.itcast.demo11;

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

public class CopyFile1 {
    public static void main(String[] args) throws IOException {
        FileReader fr = new FileReader("lib/1.txt");
        FileWriter fw = new FileWriter("lib/2.txt");

        char[] chars = new char[2048];
        int len;    //读取到的有效字符

        while ((len = fr.read(chars)) != -1) {
            fw.write(chars, 0, len);
        }
        fr.close();
        fw.close();
    }
}

在实际生产环境中,流的操作非常的缓慢、耗时(打开资源、操作资源、关闭资源),所以,实际生产环境中的流操作对效率的要求很高。为此,Java的设计者们提供了高效的缓冲流供开发者使 用。

字符缓冲流拷贝文件的标准代码 

创建字符流读文件对象:

BufferedReader br = new BufferedReader(new FileReader("readme.txt"));

创建字符流写文件对象:

BufferedWriter bw = new BufferedWriter(new FileWriter("dest.txt"));

异常处理:

throws IOException

使用while循环读写数据:

char[] chs = new char[2048];
int len;
while((len = br.read(chs)) != -1) {
bw.write(chs, 0, len);
}

关闭资源:

br.close();
bw.close();

 字符缓冲流普通用法

package com.itcast.demo11;

import java.io.*;
import java.nio.channels.NonReadableChannelException;

public class CopyFile2 {
    public static void main(String[] args) throws IOException {
        //字符缓冲自带有缓冲区,大小为8192个字符,16KB
        //创建字符缓冲输入流对象,关联目的地文件
        FileReader fr = new FileReader("lib/1.txt");
        BufferedReader br = new BufferedReader(fr);
        //简化
        BufferedReader br2 = new BufferedReader(new FileReader("lib/1.txt"));

        FileWriter fw = new FileWriter("lib/2.txt");
        BufferedWriter bw = new BufferedWriter(fw);
        //简化
        BufferedWriter bw2 = new BufferedWriter(new FileWriter("lib/2.txt"));

        int len;

        while ((len = br.read()) != -1) {
            bw.write(len);
        }

        br.close();
        bw.close();
    }
}

 字符缓冲流一次读写一行

 

package com.itcast.demo11;

import java.io.*;
import java.nio.channels.NonReadableChannelException;

public class CopyFile2 {
    public static void main(String[] args) throws IOException {
        //字符缓冲自带有缓冲区,大小为8192个字符,16KB
        //创建字符缓冲输入流对象,关联目的地文件
        BufferedReader br = new BufferedReader(new FileReader("lib/1.txt"));

        BufferedWriter bw = new BufferedWriter(new FileWriter("lib/2.txt"));

        String str;

        while ((str = br.readLine()) != null) {
            bw.write(str);
            //换行
            bw.newLine();
        }

        br.close();
        bw.close();
    }
}

 字符流只能拷贝纯文本文件。

字节流读写文件

 

字节流拷贝文件 – 按单个字节读写

创建字节流读文件对象:

InputStream is = new FileInputStream("Desktop.jpg");  

创建字节流写文件对象: 

OutputStream os = new FileOutputStream("D:\\桌面.jpg");

 异常处理:

throws IOException

使用while循环读写数据: 

int b;
while((b = is.read()) != -1) {
os.write(b);
}

关闭资源:

is.close();
os.close();
package com.itcast.demo11;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class CopyFile3 {
    public static void main(String[] args) throws IOException {
        FileInputStream fis = new FileInputStream("lib/a.jpg");
        FileOutputStream fos = new FileOutputStream("lib/b.jpg");

        int len;

        while ((len = fis.read()) != -1) {
            fos.write(len);
        }

        fis.close();
        fos.close();
    }

}

字节流拷贝文件 – 按字节数组读写

 

创建字节流读文件对象:

InputStream is = new FileInputStream("Desktop.jpg");

 创建字节流写文件对象:

OutputStream os = new FileOutputStream("D:\\桌面.jpg");

 异常处理:

throws IOException

定义字节数组,每次读取2048个字节:

byte[] b = new byte[2048];

使用while循环读写数据:

int len;
while((len = is.read(b)) != -1) {
os.write(b, 0, len);
}

关闭资源:

is.close();
os.close();
package com.itcast.demo11;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class CopyFile3 {
    public static void main(String[] args) throws IOException {
        FileInputStream fis = new FileInputStream("lib/a.jpg");
        FileOutputStream fos = new FileOutputStream("lib/b.jpg");

        //定义变量,用来接收读取到的内容
        byte[] bys = new byte[1024];
        //读取到的有效字节数
        int len;

        while ((len = fis.read(bys)) != -1) {
            fos.write(bys, 0, len);
        }

        fis.close();
        fos.close();
    }

}

字节缓冲流拷贝文件的标准代码

 

创建字节缓冲流读文件对象:

BufferedInputStream bis = new BufferedInputStream(new FileInputStream("jdk-11.0.1_doc-all.zip"));

创建字节缓冲流写文件对象:

BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("D:\\jdk-11.0.1_doc-all.zip"));

 异常处理:

throws IOException

定义字节数组,每次读取2048个字节:

byte[] bs = new byte[2048];

使用while循环读写数据:

int len;
while((len = bis.read(bs)) != -1) {
bos.write(bs, 0, len);
}

关闭资源:

bis.close();
bos.close();
package com.itcast.demo11;

import org.omg.CORBA.NO_IMPLEMENT;

import java.io.*;

public class CopyFile3 {
    public static void main(String[] args) throws IOException {
//        FileInputStream fis = new FileInputStream("lib/a.jpg");
//        BufferedInputStream bis = new BufferedInputStream(fis);
        //简化
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream("lib/a.jpg"));
        //FileOutputStream fos = new FileOutputStream("lib/b.jpg");
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("lib/b.jpg"));

        //定义变量,用来接收读取到的内容
        int len;

        while ((len = bis.read()) != -1) {
            bos.write(len);
        }

        bis.close();
        bos.close();
    }

}

案例:模拟文件上传功能

需求:使用控制台模拟实际开发中上传用户头像的功能

 完整代码

package com.itcast.demo11;

import java.io.*;
import java.util.Scanner;

public class UploadFile {
    public static void main(String[] args) throws IOException {
        File path = getPath();
        System.out.println(path);

        boolean flag = isExists(path.getName());
        if (flag) {
            //如果存在,提示用户头像已存在,上传失败
            System.out.println("用户头像已存在,上传失败");
        } else {
            //如果不存在,就上传用户头像,并提示上传成功
            upLoadFile(path);
        }


    }

    //获取要上传的用户头像路径 getPath()
    public static File getPath() {
        //提示用户录入头像路径,并接收
        Scanner sc = new Scanner(System.in);

        while (true) {
            System.out.println("请录入您要上传的用户头像路径");
            String path = sc.nextLine();
            //判断路径名(jpg,png,bmp)
            //不是就提示:您录入的不是图片,请重新输入
            if (!path.endsWith(".jpg") && !path.endsWith(".png") && !path.endsWith(".bmp")) {
                System.out.println("您录入的不是图片,请重新录入");
                continue;
            }
            //是,程序继续执行,判断路径是否存在,并且是否是文件
            File file = new File(path);
            if (file.exists() && file.isFile()) {
                return file;
            } else {
                //如果不是就提示路径不合法
                System.out.println("您录入的路径不合法,请重新录入");
            }

            //如果是,直接返回
        }
    }

    //定义一个方法,用来判断要上传的用户头像,在lib文件夹中是否存在
    public static boolean isExists(String path) {
        //将lib文件封装成File对象
        File file = new File("lib");
        //获取lib文件夹中所有的文件(夹)的名称数组
        String[] names = file.list();
        //遍历第二步获取到的数组,用获取到的数据依次和path进行比较
        for (String name : names) {
            if (name.equals(path)) {
                //如果一致,说明该用户头像已经存在了,就返回true
                return true;
            }
        }
        //如果不一致,说明该用户头像不存在,就返回false
        return false;
    }

    //定义方法,用来上传具体用户头像  path:数据源文件路径
    public static void upLoadFile(File path) throws IOException {
        //创建字节输入流,关联数据源文件
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream(path));
        //创建字节输出流,关联目的地文件
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("lib/" + path.getName()));
        //定义变量,记录读取到的数据
        int len;
        //循环读取,只要条件满足就一直读,并将读取到的数据赋值给变量
        while ((len = bis.read()) != -1) {
            //将读取到的数据写入到目的地文件中
            bos.write(len);
        }
        //释放资源
        bis.close();
        bos.close();

        System.out.println("上传完成!");
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值