Java常用工具——IO流

IO流

学习目标:

什么是IO流,IO流分类有哪些,IO流的功能是什么?

能够正确使用字节/字符缓冲流读写文件

能够正确处理IO流程序开发过程的异常

一、异常

概念

非正常情况,即异常就是程序出现的错误;

分类(顶层 Throwable)

a) 异常(Exception):常说的异常,合理的应用程序可能需要捕捉的异常,如NullPointException(空指针异常)

b)错误(Error):合理的应用程序不应该试图捕捉的问题,如StackOverFlowError(栈内存溢出)

异常处理方式

a) JVM默认的异常处理方式:在控制台打印错误信息,并终止程序;

b)开发中异常处理的方式:

♦ try—catch(finally):捕捉异常,自己处理;

try {
    //尝试执行的代码
    //代码有异常跳到catch,没有异常则运行完直接到finally
} catch(Exception e) {
    //出现可能的异常之后的处理代码
} finally {
    //一定会执行的代码,如关闭资源
}

特点: 处理完异常后,程序会继续执行;

​ 就算之前有return,finally中的代码也会继续执行完再终止 程序;

♦throws:抛出异常,交给调用者处理,调用者必须处理异常;

pubilc void test() throws Exception {}

调用者解决异常:

a) 继续也抛出异常;特点:执行结束后,程序不在执行;

b) 采用try—catch;

try {
    //尝试执行的代码
    //代码有异常跳到catch,没有异常则运行完直接到finally
    test();
} catch(Exception e) {
    //出现可能的异常之后的处理代码
    System.out.println("代码有异常");
}
System.out.println("可以继续执行");

二、IO流

概念

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

IO流作用

在本地磁盘和网络上操作数据;

分类

1、按数据流向分类:

♦输入流: 读取数据

♦输出流: 往外写数据

2、操作方式分类:

♦字节流

a) InputStream(字节输入流的顶层抽象类)

b) OutputStream(字节输出流的顶层抽象类)

♦字符流

a) Reader(字符输入流的顶层抽象类)

b) writer(字符输出流的顶层抽象类)

IO流体系(常用的)

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

Reader:FileReader(普通字符输入流),BufferedReader(高效字符输入流,也叫缓冲字符输入流,自带缓冲区,大小为8192个字符,也就是16KB)

Writer:FileWriter,BufferedWriter

2、字节流:按字节读写的数据流

InputStream: FileInputStream, BufferedInputStream

OutputStream: FileOutputStream,BuferedOutputStream

三、File类

概念

文件,文件夹,一个File对象代表磁盘上的某个文件或文件夹,即就是用来操作文件(夹)路径的;

构造方法

File(String pathname):根据字符串形式的路径来创建对应的File对象;

File(String parent, String child):根据父目录和子目录来创建对应的File对象;

File(File parent, String child):先将父目录封装成File对象,然后结合字符串形式的目录来获取新的File对象

成员方法(创建、判断、获取功能)

创建功能:文件不存在创建文件,存在则不创建 返回false

createNewFile():创建文件

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

判断功能:

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

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

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

获取功能:

getAbsolutePath(): 获取绝对路径,以盘符开头的路径

getPath(): 获取文件的相对路径,Java中是指相对于当前项目路径来讲的

getName(): 获取文件名

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

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

学习代码

package filedemo;

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

/**
 * @author: @橘子先森
 * @create: 2020-11-10 19:40
 **/

/*
**概念**
文件,文件夹,一个File对象代表磁盘上的某个文件或文件夹;
**构造方法**
File(String pathname):根据字符串形式的路径来创建对应的File对象;
File(String parent, String child):根据父目录和子目录来创建对应的File对象;
File(File parent, String child):先将父目录封装成File对象,然后结合字符串形式的目录来获取新的File对象
**成员方法(创建、判断、获取功能)**
createNewFile():创建文件
mkdir()和mkdirs():创建目录
isDirectory():判断File对象是否为目录
isFile():判断File对象是否为文件
exists():判断File对象是否存在
 */
public class Test {
    //main函数是所有程序的主入口,所有的代码都是从这里开始的
    public static void main(String[] args) throws IOException {

        //需求:将 D:\abc\1.txt 封装成File对象

        //方法一: 根据字符串形式的路径获取File对象
        //注意,Java中 \ 表示转义符,复制路径中 \ 会自动填写成  \\,或者写成 /
        //File file1 = new File("D:\\abc\\1.txt");
        File file1 = new File("D:/abc/1.txt");
        System.out.println("file1 " + file1);

        //方法二:根据字符串形式的父目录和子目录创建File对象
        File file2 = new File("D:/abc/","1.txt");
        System.out.println("file2 " + file2);

        //方式三:根据父目录File对象和字符串形式的子目录来获取File对象
        File file3 = new File("D:/abc/");
        File file4 = new File(file3,"1.txt");
        System.out.println("file4 " + file4);
        System.out.println("--------------------------");

        //创建功能
        //需求:在D:盘下创建 2.txt 文件
        File  file5 = new File("D:/2.txt");
        boolean flag1 = file5.createNewFile();
        System.out.println("flag1 " + flag1);

        //需求:在D:盘下创建abc文件夹
        File file6 = new File("d:/abc");
        boolean flag2 = file6.mkdir();  //make directory;创建单级目录
        System.out.println("flag2 " + flag2);

        //需求:在D:盘下创建abc/a/b/c文件夹
        File file7 = new File("D:/abc/a/b/c");
        boolean flag3 = file7.mkdirs(); //make directories;创建多级目录,也可以单级目录
        System.out.println("flag3 " + flag3);
        System.out.println("--------------------------");

        //判断功能
        File file8 = new File("D:/abc/a");
        //boolean flag4 = file8.isDirectory();
        //System.out.println("判断是否是文件夹 " + flag4);
        System.out.println("判断是否是文件夹 " + file8.isDirectory());
        System.out.println("判断是否是文件 " + file8.isFile());
        System.out.println("判断是否存在 " + file8.exists());

        //获取功能
        //在项目中创建一个lib文件夹,在文件夹中创建 1.txt文件
        File file9 = new File("lib/1.txt");
        //获取file9的绝对路径
        String absolutePath = file9.getAbsolutePath();
        System.out.println("绝对路径: " + absolutePath);    //绝对路径: D:\JavaStudy\lib\1.txt
        //获取file9的相对路径
        String path = file9.getPath();
        System.out.println("相对路径: " + path);    //相对路径: lib\1.txt
        //获取文件名
        String name = file9.getName();
        System.out.println("文件名: " + name);     //文件名: 1.txt

        //获取lib目录下所有文件(夹)的名称数组 String[]
        File file10 = new File("lib");
        String[] list = file10.list();
        for (String s : list) {
            System.out.print("lib目录下文件(夹)的名称数组:" + s + " ");
        }

        System.out.println();

        //获取lib目录下所有文件(夹)的File对象数组 File[]
        File[] files = file10.listFiles();
        for (File file : files) {
            System.out.print("lib目录下所有文件(夹)的File对象数组:" + file +" ");
        }

    }
}

四、字符流读写文件

1、字符流读数据(两种)——按单个字符读取

♦创建字符流读文件对象(Reader是抽象类,需用其子类)

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

♦调用方法读取数据(读取一个字符,返回该字符代表的整数 a-97(ASCII码值),若达到流的末尾,返回 -1)

int data = reader.read();

♦异常处理

throws IOException;

♦关闭资源(节约资源,提高效率)

reader.close();

代码学习

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

/**
 * @author: @橘子先森
 * @create: 2020-11-11 10:17
 **/
public class Test {
    public static void main(String[] args) throws IOException {
        //需求:通过字符流读取数据,lib包下的1.txt文件,内容 abc
        //1、创建字符流输入对象
        Reader reader = new FileReader("lib/1.txt"); //抛出FileNotFoundException异常
        //2、读取数据
        /*int read1 = reader.read();
        System.out.println(read1);  //a-97

        int read2 = reader.read();
        System.out.println(read2);  //a-98

        int read3 = reader.read();
        System.out.println(read3);  //a-99

        int read4 = reader.read();
        System.out.println(read4);  //读取不到数据 -1*/

        /*
            优化,循环
            因为不知道次数,所以用while循环
         */
        int read;   //ASCII码值,整数
        while ((read = reader.read()) != -1) {
            System.out.println(read);   //97 98 99
        }

        //3、释放资源
        reader.close(); //抛出IOException异常,FileNotFoundException异常属于OException异常所以可以不写
    }
}

2、字符流读数据——按字符数组读取

♦创建字符流读文件对象

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

♦调用方法读取数据(读取字符到数组中,返回读取的 有效 字符数,若达到流的末尾,返回 -1)

c har[] chs = new char[2048];
int len = r.read(chs);

♦异常处理

throws IOException;

♦关闭资源(节约资源,提高效率)

reader.close();

代码学习

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

/**
 * @author: @橘子先森
 * @create: 2020-11-11 10:50
 **/
public class Text {
    public static void main(String[] args) throws IOException {
        //需求:通过字符流读取数据,一次读取一个字符数组,lib包下的2.txt文件 qwertyuiop
        //1、创建字符输入流对象
        Reader reader = new FileReader("lib/2.txt");

        //2、读取数据
        //定义数组,初始长度3
        /*char[] chs = new char[3];
        int len1 = reader.read(chs);
        System.out.println(chs);    //q,w,e
        System.out.println(len1);   //3

        int len2 = reader.read(chs);
        System.out.println(chs);    //r,t,y
        System.out.println(len2);   //3

        int len3 = reader.read(chs);
        System.out.println(chs);    //u,i,o
        System.out.println(len3);   //3

        int len4 = reader.read(chs);
        System.out.println(chs);    //p,i,o 因为读取数组是覆盖,只有 g 有效覆盖了上一数组的 u
        System.out.println(len4);   //1

        int len5 = reader.read(chs);
        System.out.println(chs);    //p,i,o 没有读取到
        System.out.println(len5);   // -1*/

        /*
            优化,while循环
         */
        //定义数组
        char[] chs = new char[3];
        //定义一个变量,记录读取有效字符长度
        int len;
        while ((len = reader.read(chs)) != -1) {
            /*
                chs: 表示要操作的数组
                0: 表示起始索引
                len: 表示要操作的字符个数
             */
            //将读取到的内容,转换成字符串打印
            //String s1 = new String(chs);    //qwe rty uio pio
            String s = new String(chs,0,len);   //qwe rty uio p
            System.out.println(s);
        }

        //3、释放资源
        reader.close();
    }
}

3、字符流写数据(三种)——按单个字符写入

♦创建字符流写文件对象(Writer是抽象类,需用其子类)

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

♦调用方法写入数据

int a = '中'; //因为字符的底层是一个整数
writer.write(a);

♦异常处理

throws IOException;

♦关闭资源

writer.close();

4、字符流写数据——按字符数组写入

♦创建字符流写文件对象(Writer是抽象类,需用其子类)

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

♦调用方法写入数据

char[] chs ={'橘','子','先','森'}
writer.write(chs);

♦异常处理

throws IOException;

♦关闭资源

writer.close();

5、字符流写数据——按字符串写入

♦创建字符流写文件对象(Writer是抽象类,需用其子类)

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

♦调用方法写入数据

writer.write("橘子先森");

♦异常处理

throws IOException;

♦关闭资源

writer.close();

字符流写数据代码学习

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

/**
 * @author: @橘子先森
 * @create: 2020-11-11 12:05
 **/
public class WriterDemo {
    public static void main(String[] args) throws IOException {
        //通过字符流写数据
        //1、创建字符输出流对象
        Writer writer = new FileWriter("lib/1.txt");

        //2、写数据 (覆盖)
        //2.1一次写一个字符
        //writer.write('嗨');

        //2.2一次写一个指定字符数组
        //char[] chs = {'橘','子','先','森','啊'};
        //writer.write(chs);
        //writer.write(chs,2,3);  //先森啊

        //2.3一次写一个字符串
        writer.write("好好学习,天天向上");

        //3、释放资源
        writer.close();
    }
}

6、字符流拷贝文件(Reader和Writer同时使用)——按单个字符读写

♦创建字符流读文件对象(Reader是抽象类,需用其子类)

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

♦创建字符流写文件对象(Writer是抽象类,需用其子类)

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

♦调用方法读取数据(读取一个字符,返回该字符代表的整数 a-97(ASCII码值),若达到流的末尾,返回 -1)

int data = reader.read();

♦调用方法写入数据

writer.write(data);

♦异常处理

throws IOException;

♦关闭资源

reader.close();
writer.close();

代码学习

import java.io.*;

/**
 * @author: @橘子先森
 * @create: 2020-11-11 14:07
 **/
public class CopyFileDemo {
    public static void main(String[] args) throws IOException {
        //需求:通过字符流拷贝文件,一次读写一个字符;将1.txt中的内容复制到2.txt文件中

        //1、创建字符流读文件对象,字符输入流对象,关联数据源文件
        //Reader reader = new FileReader("lib/1.txt");
        FileReader reader = new FileReader("lib/1.txt");

        //2、创建字符流写文件对象,字符输出流对象,关联目的地文件
        //注意:如果目的地文件不存在,程序会自动创建
        FileWriter writer = new FileWriter("lib/3.txt");

        //3、调用方法读数据,定义变量记录读取到的内容
        int len;

        //4、循环读取,只要条件满足一直读取,并将读取到的内容赋值给变量
        while ((len = reader.read()) != -1) {
            //5、调用方法写数据,将读取到的数据写入到目的地文件中
            writer.write(len);
        }

        //6、释放资源
        reader.close();
        writer.close();
    }
}

7、字符流拷贝文件(Reader和Writer同时使用)——按字符数组读写

♦创建字符流读文件对象(Reader是抽象类,需用其子类)

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

♦创建字符流写文件对象(Writer是抽象类,需用其子类)

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

♦调用方法读取数据

char[] chs = new char[2048]; //最好1024整数倍,计算机底层换算单位1024

♦调用方法写入数据

writer.write(chs,0,len);

♦异常处理

throws IOException;

♦关闭资源

reader.close();writer.close();

代码学习

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

/**
 * @author: @橘子先森
 * @create: 2020-11-11 15:08
 **/
public class CopyFile2Demo {
    public static void main(String[] args) throws IOException {
        //需求:通过字符流拷贝文件,一次读写一个字符数组
        //将1.txt文件内容复制到2.txt中

        //1、创建字符输入流对象,关联源文件
        FileReader fr = new FileReader("lib/1.txt");

        //2、创建字符输出流对象,关联目的地文件
        FileWriter fw = new FileWriter("lib/2.txt");

        //3、定义变量记录读取到的内容
        //定义一个字符数组
        char[] chs = new char[1024];    //最好1024整数倍
        //定义用来记录读取到的有效字符数
        int len;

        //4、循环读取,只要满足条件一直读取,并将读取到的内容复制给变量
        while ((len = fr.read(chs)) != -1) {
            //5、调用方法写数据,将读取到的文件写入到目的地文件中
            fw.write(chs,0,len);

        }

        //6、释放资源
        fr.close();
        fw.close();
    }
}

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

(高效字符输入流,也叫缓冲字符输入流,自带缓冲区,大小为8192个字符,也就是16KB,只能拷贝 纯文本文件 )

成员方法:

readLine(); 一次读取一行数据并返回读取到的内容,读取不到返回null;

newLine();根据当前操作系统给出对应的换行符;

♦创建字符流读文件对象

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

♦创建字符流写文件对象

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

♦异常处理

throws IOException;

♦使用while循环读取数据

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

♦关闭资源

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

代码学习

import java.io.*;

/**
 * @author: @橘子先森
 * @create: 2020-11-11 17:48
 **/
public class CopyFile3Demo {
    public static void main(String[] args) throws IOException {
        //需求:通过字符缓冲流流拷贝文件
        //将1.txt文件内容复制到2.txt中

        //1、创建字符输入流对象,关联源文件
        FileReader fr = new FileReader("lib/1.txt");
        BufferedReader br = new BufferedReader(fr);

        //2、创建字符输出流对象,关联目的地文件
        BufferedWriter bw = new BufferedWriter(new FileWriter("lib/2.txt"));    //简化

        //3、定义变量记录读取到的内容

        int len;

        //4、循环读取,只要满足条件一直读取,并将读取到的内容复制给变量
        while ((len = br.read()) != -1) {
            //5、调用方法写数据,将读取到的文件写入到目的地文件中
            bw.write(len);

        }

        //6、释放资源
        fr.close();
        br.close();
        bw.close();
    }
}

五、字节流读写文件

1、字节流拷贝文件——按单个字节读写

♦创建字节流读文件对象

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

♦创建字节流写文件对象

OutputStream os = new FileOutoutStream("D:\\a.jpg");

♦异常处理

throw IOException;

♦使用while循环读写数据

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

♦关闭资源

is.close();
os.close();

代码学习

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

/**
 * @author: @橘子先森
 * @create: 2020-11-11 21:31
 **/
public class CopyFile5Demo {
    public static void main(String[] args) throws IOException {
        //需求:通过普通字节流,一次读写一个字节的方式,将a.jpg 复制到 b.jpg 中
        //1、创建字节输入流,关联数据源文件
        FileInputStream fis = new FileInputStream("lib/a.jpg");

        //2、创建字节输出流,关联目的地文件
        FileOutputStream fos = new FileOutputStream("lib/b.jpg");

        //3、定义变量,用来记录读取到的内容
        int len;

        //4、循环读取,只要条件满足就一直读,并将读取到的内容赋值给变量
        while ((len = fis.read()) != -1) {
            //5、将读取到的内容写入到目的地文件中
            fos.write(len);
        }

        //6、释放内存
        fis.close();
        fos.close();
    }
}

2、字节流拷贝文件——按字节数组读写

♦创建字节流读文件对象

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

♦创建字节流写文件对象

OutputStream os = new FileOutoutStream("D:\\a.jpg");

♦异常处理

throw 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();

代码学习

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

/**
 * @author: @橘子先森
 * @create: 2020-11-11 21:31
 **/
public class CopyFile6Demo {
    public static void main(String[] args) throws IOException {
        //需求:通过普通字节流,一次读写一个字节数组的方式,将a.jpg 复制到 b.jpg 中
        //1、创建字节输入流,关联数据源文件
        FileInputStream fis = new FileInputStream("lib/a.jpg");

        //2、创建字节输出流,关联目的地文件
        FileOutputStream fos = new FileOutputStream("lib/b.jpg");

        //3、定义变量,用来记录读取到的内容
        byte[] bys = new byte[2048];
        //用来记录读取到的有效字节数
        int len;

        //4、循环读取,只要条件满足就一直读,并将读取到的内容赋值给变量
        while ((len = fis.read()) != -1) {
            //5、将读取到的内容写入到目的地文件中
            fos.write(bys,0,len);
        }

        //6、释放内存
        fis.close();
        fos.close();
    }
}

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

♦创建字节流读文件对象

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

♦创建字节流写文件对象

OutputStream os = new FileOutoutStream("D:\\a.jpg");

♦异常处理

throw 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 demo1;

import java.io.*;

/**
 * @author: @橘子先森
 * @create: 2020-11-11 21:31
 **/
public class CopyFile7Demo {
    public static void main(String[] args) throws IOException {
        //需求:通过字节缓冲流,将a.jpg 复制到 b.jpg 中
        //1、创建字节输入流,关联数据源文件
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream("lib/a.jpg"));

        //2、创建字节输出流,关联目的地文件
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("lib/b.jpg"));

        //3、定义变量,用来记录读取到的内容
        //用来记录读取到的有效字节数
        int len;

        //4、循环读取,只要条件满足就一直读,并将读取到的内容赋值给变量
        while ((len = bis.read()) != -1) {
            //5、将读取到的内容写入到目的地文件中
            bos.write(len);
        }

        //6、释放内存
        bis.close();
        bos.close();
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值