14、java——IO流

3、IO流

(1)前提需求: 读写文件内部的内容,上传,下载

(2)流: 管道  数据以先入先出的方式进行流动,数据源--数据-->目的地

(3)io包: 一系列io相关类  File...

(4)流的分类:

        ①按照流向分:

            输入流,输出流

 (以大脑为中心,以程序为中心,明确数据源和目的地,能够确定输入还是输出)

        ②按照操作单元分;

字节流 : 万能流,任意内容都能转为字节,字符流 : 只能传输纯文本的内容

        ③按照功能分:

节点流 : 真实做读入写出的流,功能流 : 增强节点流的功能,加强性能

分类之间是相辅相成的

(5)字节流:

        ①字节输入流 InputStream

            文件字节输入流 FileInputStream

                功能: 节点流    流向分:输入流   操作单元:字节流

                功能: 读入read()   关闭close

②字节输出流 OutputStream

public class Class001_IO {

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

        //FileInputStream(File file) 通过打开与实际文件的连接来创建 FileInputStream ,该文件由文件系统中的 File对象 file命名。

        File src = new File("D://test2.txt"); //数据源

        //创建流

        InputStream is = new FileInputStream(src);

        //读入数据 int read() 从此输入流中读取一个字节的数据。  读到文件末尾返回-1

        int num = is.read();

        //处理数据

        System.out.println((char)num);

        System.out.println((char)(is.read()));

        System.out.println((char)(is.read()));

        System.out.println(is.read());

        //关闭流

        is.close();

    }

}

③read() 从此输入流中读取一个字节的数据。  读到文件末尾返回-1

      每次读取一个字节,重复通过循环读入,可以简化代码结构

 

public class Class002_IO {

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

        //创建流

        //FileInputStream (String name) 通过打开与实际文件的连接来创建 FileInputStream ,该文件由文件系统中的路径名 name命名。

        InputStream is = new FileInputStream("D://test2.txt");

        //读入数据

        int num = -1;

        while((num=is.read())!=-1){

            //处理数据

            System.out.println((char)num);

        }

        //关闭流

        is.close();

    }

}

④public byte[] readAllBytes() throws IOException

     从输入流中读取所有剩余字节。 此方法将阻塞,直到读取了所有剩余字节并检测到流结束,或者抛出异常。 此方法不会关闭输入流。

     当此流到达流的末尾时,此方法的进一步调用将返回空字节数组,请注意,此方法适用于方便将所有字节读入字节数组的简单情况。 它不用于读取包含大量数据的输入流。起始版本: java9

public class Class004_IO {

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

        //1.构建流

        InputStream is = new FileInputStream("D://test2.txt");



        //2.读入所有数据

        byte[] arr = is.readAllBytes();

        //3.处理数据

        System.out.println(new String(arr));



        //4.关闭

        is.close();

    }

}

(6)字节输出流

      ①OutputStream 此抽象类是表示输出字节流的所有类的超类。

      ②FileOutputStream : 文件输出流,将数据写出到指定文件中

③注意:如果目的地文件不存在,系统会自动创建

             输出流如果目的地文件存在,内容默认覆盖,设置追加

(7)文件拷贝,数据源--> 读入---> 程序 --> 写出 --> 目的地

步骤:①创建流(输入 输出)②准备小汽车 字节数组③读入-->写出④刷出⑤关闭(后打开的先关闭)

public class Class006_CopyFile {

    public static void main(String[] args){

        //1.创建流(输入 输出)

        //作用域提升,为了能够在finally中使用

        InputStream is = null;

        OutputStream os = null;

        try {

            is = new FileInputStream("D://test.txt");

            os = new FileOutputStream("D://dest.txt");

            //2.准备小汽车 字节数组

            byte[] car = new byte[1024];

            //3.读入-->写出

            int len = -1; //记录每次读入到字节数组中数据的个数

            while((len=is.read(car))!=-1){

                //读入多少字节数据写出多少字节数据

                os.write(car,0,len);

            }

            //4.刷出

            os.flush();

        } catch (FileNotFoundException e) {

            e.printStackTrace();

        } catch (IOException e) {

            e.printStackTrace();

        } finally {

            //5.关闭(后打开的先关闭)

            //预防空指针异常出现

            if(os!=null){

                try {

                    os.close();

                } catch (IOException e) {

                    e.printStackTrace();

                }

            }

            if(is!=null){

                try {

                    is.close();

                } catch (IOException e) {

                    e.printStackTrace();

                }

            }

        }

    }

}

 

(8)字符输入流  : 只能读写纯文本数据

①输入流 : Reader 字符输入流的父类FileReader 文件字符输入流read(),read(char[]),close()

②输出流 : Writer

public class Class001_IO {

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

        //1.创建流

        //FileReader(String fileName)

        //FileReader(File file)

        Reader rd = new FileReader("D://test.txt");



        //2.读入

        //char ch = (char)(rd.read());

        //小汽车

        char[] car = new char[1024];



        //循环读入

        int len = -1;

        while((len = rd.read(car))!=-1){

            //3.处理数据

            System.out.println(new String(car,0,len));

        }



        //4.关闭

        rd.close();

    }

}

   ③输出流 : Writer 字符输出流抽象父类,FileWriter 文件字符输出流write(),flush(),close()

public class Class002_IO {

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

        //1.创建流

       /*

        //FileWriter(File file)

        //FileWriter(String fileName)

        //FileWriter(File file, boolean append)

        //FileWriter(String fileName, boolean append)

*/
        Writer rt = new FileWriter("D://test.txt",true);



        //2.准备数据

        String msg = "今天也要加油鸭!!!";



        //3.写出

        rt.write(msg);



        //4.刷出

        rt.flush();



        //5.关闭

        rt.close();

    }

}

   ④字符流实现文件拷贝,注意: 只能为纯文本文件

1、拷贝文件夹 :

(1)判断要拷贝的文件是文件还是文件夹

是文件: 调用工具类实现文件拷贝

是文件夹: 创建文件夹,遍历数据源文件夹,获取到所有的子文件然后重复

public static void main(String[] args) {
        copyDir("D://DDD","D://haha");
    }
    //拷贝文件夹
    public static void copyDir(String src,String dest){
        copyDir(src!=null?new File(src):null,dest!=null?new File(dest):null);
    }
    public static void copyDir(File src, File dest){
        if(src==null || dest==null){
            throw new NullPointerException();
        }
        if(!src.exists()){
            System.out.println("数据源不存在!!!");
            return;
        }
        //拷问文件夹|文件
        copyDetail(src,dest);
    }
    //实现拷贝细节
    public static void copyDetail(File src,File dest){
        //拼接完整目的地路径
        dest = new File(dest,src.getName());  //D:\haha\hehe\DDD
        //文件
        if(src.isFile()){
            //如果目的地路径不存在
           if(!dest.getParentFile().exists()){
               dest.getParentFile().mkdirs();
           }
            //文件拷贝
            CopyFileUtils.copyFile(src,dest);

        }else if (src.isDirectory()){
            //文件夹
            //创建不存在的目的地路径
            dest.mkdirs();
            //遍历数据源
            File[] arr = src.listFiles();
            for(File file:arr){   //D:\DDD\a.txt
                copyDetail(file,dest);  ////D:\haha\hehe\DDD
            }
        }
    }
}

    (2)按照功能分:

        ①节点流 : 真实做读入写出②功能流 : 加强性能③功能流都要包裹节点流使用

④缓冲流 : 功能流⑤作用: 提高读写效率

⑥字节节点流:

            FileInputStream 文件流 | ByteArrayInputStream 字节数组流

            FileOutputStream | ByteArrayOutputStream

⑤字节缓冲流 : 字节流功能流的一种

            BufferedInputStream 字节输入缓冲流

            BufferedOutputStream 字节输出缓冲流

⑥无新增功能,可以发生多态

⑦字符节点流

            FileReader,FileWriter

⑧字符缓冲流

            BufferedReader,BufferedWriter

存在新增方法: 不能发生多态

                readLine(),newLine()

public class Class001_Buffered {

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

        //1.创建流

        InputStream is = new BufferedInputStream(new FileInputStream("D://test.txt"));

        OutputStream os = new BufferedOutputStream(new FileOutputStream("D://heihei.txt"));

        //2.拷贝

        byte[] car = new byte[1024];

        int len = -1;

        while((len=is.read(car))!=-1){

            os.write(car,0,len);

        }

        //3.刷出

        os.flush();

        //4.关闭

        os.close();

        is.close();

    }

}

 

2、基本数据类型流|Data流

(1)功能: 功能流   操作单元: 字节流

(2)作用: 保留数据已经数据类型(基本数据类型+String)

DataInputStream,新增功能:  readXxx()

DataOutputStream,新增功能:  writeXxx()

(3)注意:①读入与写出的顺序要保持一致②java.io.EOFException : 读入的文件不是源文件

public class Class001_Data {

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

        readFromFile("D:/d.txt");

    }

    //读入

    public static void readFromFile(String path) throws IOException {

        //1.创建流

        DataInputStream is = new DataInputStream(new BufferedInputStream(new FileInputStream(path)));

        //2.读入

        int i = is.readInt();

        boolean flag = is.readBoolean();

        char ch = is.readChar();

        String s = is.readUTF();

        //3.处理数据

        System.out.println(i);

        System.out.println(flag);

        System.out.println(ch);

        System.out.println(s);

        //4.关闭

        is.close();

    }

    //写出

    public static void writeToFile(String path) throws IOException {

        //1.创建输出流

        DataOutputStream out = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(path)));

        //2.准备数据

        int i = 1;

        boolean flag = false;

        char ch = 'c';

        String str = "哈哈";

        //3.写出

        out.writeInt(i);

        out.writeBoolean(flag);

        out.writeChar(ch);

        out.writeUTF(str);

        //4.刷出

        out.flush();

        //5.关闭

        out.close();

    }

}

3、Object 流| 对象流 | 引用数据类型流

(1)作用: 读写对象数据|引用数据类型的数据(包含基本数据类型)

ObjectInputStream  反序列化输入流,新增功能: readObject()

ObjectOutputStream 序列化输出流,新增功能: writeObject(Object obj)

(2)序列化: 将对象数据转换一个可存储或者可传输的状态过程

(3)特性:

①先序列化后反序列化

        ②不能所有的类型都能序列化  java.io.Serializable

        ③不是所有的属性都需要序列化

        ④静态的内容不会序列化

        ⑤如果父类实现序列化,子类没有实现,可以序列化所有的成员

        ⑥如果子类实现序列化,父类实现,只能序列化子类成员

(4)通过序列号控制版本不一致问题:

        ①实现Serializable接口的类型默认生成序列号,序列号会根据成员的修改做更新  serialVersionUID = -5204947308809070324

        ②控制版本的统一问题: 控制类型修改之前与之后序列不变

        ③通过工具生成序列号: a.实现Serializable接口  b.setting设置  c.选中类名->alt+enter->生成序列号

public class Class001_Object {

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

        //writeToFile("D://e.txt");

        readFile("D://e.txt");

    }

    //反序列化

    public static void readFile(String path) throws IOException, ClassNotFoundException {

        //1.输入流

        ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(new FileInputStream(path)));

        //2.读入

        User obj1 = (User) in.readObject();

        int[] arr = (int[]) in.readObject();

        //3.处理数据

        System.out.println(obj1);

        System.out.println(Arrays.toString(arr));

        //4.关闭

        in.close();

    }

    //序列化输出

    public static void writeToFile(String path) throws IOException {

        //1.输出流

        ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(path)));

        //2.数据

        User user = new User("zhangsan",18,"123");

        int[] arr = {1,2,3,4};

        //3.写出

        out.writeObject(user);

        out.writeObject(arr);

        //4.刷出

        out.flush();

        //5.关闭

        out.close();

        //修饰user对象的成员,静态

        user.username = "lisi";

        user.password = "4321";

    }

}

class User implements Serializable{

    private static final long serialVersionUID = -5204947308809070324L;

    public String username;

    //transient 修饰的字段不会序列化

    public transient int age;

    public static String password;

    //成员的修改: 新增的成员

    public int vip;

    public int id;  //用户编号

    public User() {

    }

    public User(String username, int age, String password) {

        this.username = username;

        this.age = age;

        this.password = password;

    }

    @Override

    public String toString() {

        return "User{" +

                "username='" + username + '\'' +

                ", age=" + age +

                ", password='" + password + '\'' +

                '}';

    }

}

(1)CommonsIO 是apache的一个开源的工具包,封装了IO操作的相关类,使用Commons IO可以很方便的读写文件,url源代码等。

(2)使用第三方组件的方式|步骤:

        ①下载源码资源,找到核心jar包

        ②项目下新建文件夹lib,放入jar包

        ③commons-IO 需要加入classpath 的第三方 jar 包内的 class 文件才能在项目中使用,选中jar包右键->add as lib...

public class Class001_CommonsIO {

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

        //1.创建File对象

        File src = new File("D://a.txt");

        File dest = FileUtils.getFile("D://f.txt");

        //FilenameUtils

        //isExtension(String fileName, String text) // 判断fileName是否是text后缀名

        //FilenameUtils.getBaseName(String filename) // 去除目录和后缀后的文件名       System.out.println(FilenameUtils.getBaseName("D://DDD/haha.txt"));;        System.out.println(FilenameUtils.getName("D://DDD/haha.txt"));;       System.out.println(FilenameUtils.isExtension("D://DDD/haha.txt","txt"));;

        //FileUtils

        //FileUtils.copyFile(File srcFile, File destFile)` // 复制文件

        FileUtils.copyFile(src,dest);

        // **复制文件夹**

        //FileUtils.copyDirectory(File srcDir, File destDir)` // 复制文件夹(文件夹里面的文件内容也会复制)

        FileUtils.copyDirectory(new File("D://DDD"), new File("D://hehe/DDD"));

        //FileUtils.copyDirectory(File srcDir, File destDir, FileFilter filter)` // 复制文件夹,带有文件过滤功能

        FileUtils.copyDirectory(new File("D://DDD"),  new File("D://houhou/DDD"), FileFilterUtils.fileFileFilter());

        //**把字符串写入文件**

        //`FileUtils.writeStringToFile(File file, String data, String encoding)`  // 字符串以指定的编码写到文件

        //`FileUtils.writeStringToFile(File file, String data, String encoding, boolean append)`// 指定知否追加

        FileUtils.writeStringToFile(src,"yyds!!!!","UTF-8",true);

    }

}

 

posted @ 2021-07-21 14:25  孤影_空白  阅读(100)  评论(0编辑  收藏  举报