IO流起来1

文件

什么是文件

文件是保存数据的地方。
比如:word文档,text文件,excel文件等都是文件。它既可以保存一张图片,也可以保存视频

文件流

文件在程序中是以流的形式来操作的

  • 流:数据在数据源(文件)和程序(内存)之间经历的路径
  • 输入流:数据从数据源(文件)到程序(内存)的路径
  • 输出流:数据从程序(内存)到数据源(文件)的路径
    在这里插入图片描述

常用文件操作

创建文件对象相关构造器和方法

相关方法

  • 1,new File(String pathname):根据路径构建一个File对象
  • 2,new File(File parent,String child):根据父目录文件+子路径构建
  • 3,new File(String parent,String child):根据父目录+子路径构建
import org.junit.Test;

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

public class FileInformation {
    public static void main(String[] args) throws IOException {
        //方式1,new File(String pathname):根据路径构建一个File对象
        //先创建文件对象
        String filePath = "d:\\new2.txt";
        File file = new File(filePath);
        file.createNewFile();
        System.out.println("方式1文件创建成功");


    }

    public void create02() throws IOException {
        //方式2,new File(File parent,String child):根据父目录文件+子路径构建
        File file1 = new File("d:\\");
        String fileName = "new3.txt";
        //这里的file对象,在java程序中只是一个对象
        //只有执行了,createNewFile方法,才会真正的在磁盘创建该文件
        File file2 = new File(file1, fileName);
        file2.createNewFile();
        System.out.println("方式2,创建成功");
    }
    @Test
    public void creat03() throws IOException {
        //方式3:new File(String parent,String child):根据父目录+子路径构建
        String parentPath = "d:\\";
        String fileName = "new4.txt";

        File file = new File(parentPath, fileName);
        file.createNewFile();
        System.out.println("方式3,创建成功");
    }
}

获取文件的相关信息

先创建文件对象:
File file = new File(“e:\news1.txt”);
方法:
System.out.println(“文件名字=”+ file.getName());
System.out.println(“文件绝对路径=” + file.getAbsolutePath());
System.out.println(“文件父级目录=” + file.getParent());
System.out.println(“文件大小(字节)=” + file.length());
System.out.println(“文件是否存在=” + file.exists());//T
System.out.println(“是不是一个文件=” + file.isFile());//T
System.out.println(“是不是一个目录=” + file.isDirectory());//

目录的操作和文件删除

  • mkdir创建一级目录
  • mkdirs创建多级目录
  • delete:删除空文件或目录

在这里插入图片描述

public class Directory_ {
    public static void main(String[] args) {

    }
    //判断d:\\new1.txt 是否存在,如果存在就删除
    @Test
    public void m1 (){
        String filePath = "d:\\new1.txt";
        File file = new File(filePath);
        if (file.exists()){
            if(file.delete()){
                System.out.println("删除成功");
            }else{
                System.out.println("删除失败");
            }
        }else{
            System.out.println("该文件不存在");
        }
    }
    //判断d:\\new 是否存在,如果存在就删除.否则提示不存在
    //这里我们需要体会到,在java编程中,目录也被当做文件
    @Test
    public void m2 (){
        String filePath = "d:\\new";
        File file = new File(filePath);
        if (file.exists()){
            if(file.delete()){
                System.out.println("删除成功");
            }else{
                System.out.println("删除失败");
            }
        }else{
            System.out.println("该文件不存在");
        }
    }
    //判断d:\\B站.txt 是否存在,如果存在就提示已经存在,否则就创建
    @Test
    public void m3 (){
        String filePath = "D:\\new\\a\\b\\c";
        File file = new File(filePath);
        if (file.exists()){
                System.out.println("目录存在");
            }else{
                if (file.mkdirs()){
                    System.out.println("该目录创建成功");
                }else {
                    System.out.println("创建失败");
                }
            }
        }

    }

IO流原理及流的分类

JavaIO流原理

  • 1,I/O 是 Input/Output 的缩写,I/O 技术是非常使用的技术,用于处理数据传输。如:读/写文件,网络通讯等
  • 2,Java程序中,对于数据的输入/输出操作,以“流(stream)”的方式进行
  • 3,java.io包下提供了各种“流”类和接口,用以获取不同种类的数据,并通过方法输入和输出数据
  • 4,输入input:读取外部数据(磁盘、光盘等存储设备的数据)到程序(内存)中
  • 5,输出output:将程序(内存)数据输出到磁盘、光盘等存储设备中

流的分类

  • 1,按操作数据单位不同分为:字节流(8 bit)二进制文件,字符流(按字符)文本文件
  • 2,按数据流的流向不同分为:输入流,输出流
  • 3,按流的角色的不同分为:节点流、处理流/包装流
    在这里插入图片描述

IO流体系图

在这里插入图片描述

IO流常用的类:节点流、处理流/包装流

节点流

演示 FileInputStream 的使用(字节输入流 文件–> 程序)

  • 单个字节(read())的读取,效率比较低
  • 字节组read(byte[] b)的读取,效率比较高
import org.junit.Test;

import java.io.FileInputStream;
import java.io.IOException;
//单个字节的读取,效率比较低
public class FileInputStream_ {
    //使用 read()
    public void readFiled01() {
        String filePath = "d:\\new2.txt";
        int readDate = 0;
        //创建FileInputStream对象,用于读取文件
        FileInputStream fileInputStream = null;
        try {
            //创建FileInputStream对象,用于读取文件
            fileInputStream = new FileInputStream(filePath);
            //从该输入流读取(read)一个字节的数据,如果没有输入可用(-1),此方法将阻止
            while ((readDate = fileInputStream.read()) != -1) {
                System.out.print((char) readDate);//转成char显示
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {//关闭文件流,释放资源
            try {
                fileInputStream.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }

    }

    //使用 read(byte[] b)
    @Test
    public void readFiled02() {
        String filePath = "d:\\new2.txt";
        byte[] buf = new byte[8];//一次读取8个字节
        int readLen = 0;
        //创建FileInputStream对象,用于读取文件
        FileInputStream fileInputStream = null;
        try {
            //创建FileInputStream对象,用于读取文件
            fileInputStream = new FileInputStream(filePath);
            //从该输入流读取最多 b.length 字节的数据到字节数组。 此方法将阻塞,直到某些输入可用。
            //如果返回-1 , 表示读取完毕
            //如果读取正常, 返回实际读取的字节数
            while ((readLen = fileInputStream.read(buf)) != -1) {
                System.out.print(new String(buf,0,readLen));//转成char显示
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {//关闭文件流,释放资源
            try {
                fileInputStream.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }

    }
}


演示使用 FileOutputStream :将数据(字节流)写到文件中,如果该文件不存在,则创建该文件

  • 两种创建方式:
    1,new FileOutputStream(filePath) 创建方式,当写入内容时,会覆盖原来的内容
    2,new FileOutputStream(filePath,true) 创建方式,当写入内容时,是追加到文件后面
  • 三种写入方式
    1,写入一个字节 fileOutputStream.write(‘H’);
    2,写入字符串 String str = “hsp,world!”; str.getBytes() 可以把 字符串-> 字节数组
    3,write(byte[] b , int off , int len)将len个字节从位于 偏移量 的off开始,将指定字节数组写入此文件输出流
import org.junit.Test;

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

public class FileOutputStream_ {
    //演示使用FileOutputStream,将数据写到文件中
    //如果文件不存在,则创建该文件
    @Test
    public void writeFile(){
        //定义文件
        String filePath = "d:\\a.txt";
        //创建 FileOutputStream 对象
        FileOutputStream fileOutputStream = null;
        try {
            //得到 FileOutputStream 对象
            //说明:
            //1,new FileOutputStream(filePath)  创建方式,当写入内容时,会覆盖原来的内容
            //2,new FileOutputStream(filePath,true) 创建方式,当写入内容时,是追加到文件后面
            fileOutputStream = new FileOutputStream(filePath,true);
            //1,写入一个字节
//            fileOutputStream.write('H');

            //2,写入字符串
            String str = "aaa,world";
            //str.getBytes() 可以把字符串-->字节数组
//            fileOutputStream.write(str.getBytes());

            //3,write(byte[] b , int off , int len)将len个字节从位于偏移量的off开始,将指定字节数组写入此文件输出流
           // 位置
            fileOutputStream.write(str.getBytes(),0,3);
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            try {
                fileOutputStream.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }

}

FileOInputStream输入流 和 FileOutputStream 输出流的使用:拷贝文件

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

public class FileCopy {
    public static void main(String[] args) {


    //将D盘中的 D:\\1.gif  拷贝到  到d盘
    //思路分析
    //1,创建文件输入流,将文件写入城西
    //2,创建文件输出流,将读取到的文件数据,写入到指定文件
    String srcFilePath = "d:\\1.gif";
    String destFilePath = "d:\\11.jpg";
    FileInputStream fileInputStream = null;
    FileOutputStream fileOutputStream = null;

        try {
            fileInputStream = new FileInputStream(srcFilePath);
            fileOutputStream = new FileOutputStream(destFilePath);
            //定义一个字节数组,提高读取效果
            byte[] buf = new byte[1024];
            int readLen = 0;
            while ((readLen = fileInputStream.read(buf)) != -1) {
                //读取到后,就写入到文件 通过 fileOutputStream
                //即,是一边读,一边写
                fileOutputStream.write(buf, 0, readLen);//一定要使用这个方法
            }
            System.out.println("拷贝!!");
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            //关闭输入流和输出流,释放资源
            if (fileInputStream != null){
                try {
                    fileInputStream.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }

            }
            if (fileOutputStream != null){
                try {
                    fileOutputStream.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }

    }
}

FileReader 和 FileWriter 介绍(字符流)

  • FileReader (文件输入)相关方法:
    在这里插入图片描述
    FileReader 的案例:使用 FileReader 从 story.txt 读取内容,并显示
    分别使用read() 和 read(char[])
import org.junit.Test;

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

public class FileReader_ {
    @Test
    //单个字符读取文件
    public void readFile01() {
        String filePath = "d:\\story.txt";
        FileReader fileReader = null;
        int data = 0;
        //1. 创建 FileReader 对象
        try {
            fileReader = new FileReader(filePath);
        //循环读取 使用 read, 单个字符读取
            while ((data = fileReader.read()) != -1) {
                System.out.print((char) data);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (fileReader != null) {
                    fileReader.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    //字符组读取文件
    public void readFile02() {
        System.out.println("~~~readFile02 ~~~");
        String filePath = "d:\\story.txt";
        FileReader fileReader = null;
        int readLen = 0;
        char[] buf = new char[8];
        //1. 创建 FileReader 对象
        try {
            fileReader = new FileReader(filePath);
        //循环读取 使用 read(buf), 返回的是实际读取到的字符数
        //如果返回-1, 说明到文件结束
            while ((readLen = fileReader.read(buf)) != -1) {
                System.out.print(new String(buf, 0, readLen));
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (fileReader != null) {
                    fileReader.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
  • FileWriter (文件输出)常用方法
    在这里插入图片描述
    FileWriter 的使用案例:使用 FileWriter 将 “风雨之后,定见彩虹” 写入到 note.txt 文件中, 注意细节
import java.io.FileWriter;
import java.io.IOException;

public class FileWriter_ {
    public static void main(String[] args) {
        String filePath = "d:\\note.txt";
        //创建 FileWriter 对象
        FileWriter fileWriter = null;
        char[] chars = {'a', 'b', 'c'};
        try {
            fileWriter = new FileWriter(filePath);//默认是覆盖写入
            // 3) write(int):写入单个字符
            fileWriter.write('H');
            // 4) write(char[]):写入指定数组
            fileWriter.write(chars);
            // 5) write(char[],off,len):写入指定数组的指定部分
//            fileWriter.write("帅哥".toCharArray(), 0, 3);
            // 6) write(string):写入整个字符串
            fileWriter.write(" 你好北京~");
            fileWriter.write("风雨之后,定见彩虹");
            // 7) write(string,off,len):写入字符串的指定部分
            fileWriter.write("上海天津", 0, 2);
            //在数据量大的情况下,可以使用循环操作.
             } catch (IOException e) {
            e.printStackTrace();
        } finally {

            try {
                //fileWriter.flush();
                //关闭文件流,等价 flush() + 关闭
                fileWriter.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        System.out.println("程序结束...");
    }

}

节点流和处理流

基本介绍

  • 1,节点流可以从一个特定的数据源读写数据,如:FileReader FileWriter
    在这里插入图片描述

  • 2,处理流**(包装流)** 是“连接”在已存在的流(节点流火处理流),为程序提供更为强大的读写功能,也更加灵活,如:BufferedReader、BufferedWriter
    在这里插入图片描述

节点流和处理流一览图

在这里插入图片描述

节点流和处理流的区别和联系

  • 1,节点流式底层流/低级流,直接跟数据源相接。
  • 2,处理流**(包装流)**包装节点流,既可以消除不同节点流的实现差异,也可以提供更方便的方法来完成输入输出
  • 3,处理流对节点流进行包装,使用了修饰器模式,不会直接与数据源相连

处理流的功能主要体现在以下两个方面

  • 1,性能的提高:主要以增加缓冲的方式来提高输入输出的效率
  • 2,操作的便捷:处理流可能提供了一些列便捷的方法来一次输入输出大批量的数据,使用更加灵活方便

处理流-BufferedReader 和 BufferedWriter

  • BufferedReader 和 BufferedWriter 属于字符流,是按照字符来读取数据的
  • 关闭处理流,只需要关闭外层留即可

案例:使用BufferedReader 读取文本文件,并显示在控制台

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

public class BufferedReader_ {
    public static void main(String[] args) throws IOException {
        String filePath = "d:\\story.txt";
        //创建BufferedReader
        BufferedReader bufferedReader = new BufferedReader(new FileReader(filePath));
        //读取:按行读取-效率高
        String line;
        //1. bufferedReader.readLine() 是按行读取文件
        //2. 当返回 null 时,表示文件读取完毕
        while ((line = bufferedReader.readLine())!=null){
            System.out.println(line);
        }
        //关闭流, 这里注意,只需要关闭 BufferedReader ,因为底层会自动的去关闭 节点流
        bufferedReader.close();

    }
}

案例:使用BufferedWriter 将“hello,帅哥”,写入到文件中

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;

public class Bufferedwriter_ {
    public static void main(String[] args) throws IOException {
        String filePath = "d:\\new3.txt";
        //创建BufferedWriter对象
        //说明:
        //1. new FileWriter(filePath, true) 表示以追加的方式写入
        //2. new FileWriter(filePath) , 表示以覆盖的方式写入
        BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(filePath));
        bufferedWriter.write("hello,帅哥");
        bufferedWriter.newLine();
        bufferedWriter.write("hello2,帅哥");
        bufferedWriter.newLine();
        bufferedWriter.write("hello3,帅哥");
//说明:关闭外层流即可 , 传入的 new FileWriter(filePath) ,会在底层关闭
        bufferedWriter.close();
    }
}

案例:使用BufferedReader 和 BufferedWriter完成文本文件拷贝

    1. BufferedReader 和 BufferedWriter 是安装字符操作
    1. 不要去操作 二进制文件[声音,视频,doc, pdf ], 可能造成文件损坏
import java.io.*;

//1. BufferedReader 和 BufferedWriter 是安装字符操作
//2. 不要去操作 二进制文件[声音,视频,doc, pdf ], 可能造成文件损坏
public class BufferedCopy_ {
    public static void main(String[] args) {
        String srcFilePath = "d:\\story.txt";
        String destFilePath = "d:\\story2.txt";
        BufferedReader br = null;
        BufferedWriter bw = null;
        String line;
        try {
            br = new BufferedReader(new FileReader(srcFilePath));
            bw = new BufferedWriter(new FileWriter(destFilePath));
            //说明: readLine 读取一行内容,但是没有换行
            while ((line=br.readLine())!=null){
                bw.write(line);
                bw.newLine();

            }
            System.out.println("拷贝完毕");
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            try {
                if(br != null) {
                    br.close();
                }
                if(bw != null) {
                    bw.close();
                }
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }

    }
}

处理流-BufferedInputStream 和 BufferedOutputStream

介绍 BufferedInputStream

在这里插入图片描述
在这里插入图片描述

介绍 BufferedOutputStream

在这里插入图片描述
在这里插入图片描述
案例:编程完成图片/音乐的拷贝(用Buffered 流)

import java.io.*;

//演示使用 BufferedOutputStream 和 BufferedInputStream 使用
//使用他们,可以完成二进制文件拷贝.
//思考:字节流可以操作二进制文件,可以操作文本文件吗?当然可以
public class BufferedCopy_01 {
    public static void main(String[] args) {
        String srcFilePath = "d:\\1.gif";
        String destFilePath = "d:\\11.gif";

        //创建 BufferedOutputStream 对象 BufferedInputStream 对象
        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;

        //因为 FileInputStream 是 InputStream 子类
        try {
            bis = new BufferedInputStream(new FileInputStream(srcFilePath));
            bos = new BufferedOutputStream(new FileOutputStream(destFilePath));
            //循环的读取文件,并写入到 destFilePath
            byte[] buff = new byte[1024];
            int readLen = 0;
            //当返回 -1 时,就表示文件读取完毕
            while ((readLen = bis.read(buff)) != -1) {
                bos.write(buff, 0, readLen);
            }
            System.out.println("文件拷贝完毕~~~");
        }
        catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if(bis != null) {
                    bis.close();
                }
                if(bos != null) {
                    bos.close();
                }
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

对象流-ObjectInputStream 和 ObjectOutputStream(也是处理流)

  • 功能:提供了对基本类型或对象类型的序列化和反序列化的方法
    ObjectInputStream 提供 序列化功能
    ObjectOutputStream 提供 反序列化功能
    在这里插入图片描述
    在这里插入图片描述

  • 序列化和反序列化
    1,序列化:在保存数据时,保存数据的值数据类型
    2,反序列化:在恢复数据时,恢复数据的值数据类型
    3,需要让某个对象支持序列化机制,则必须让其类可序列化-为了让某个类是可序列化的,该类必须实现如下两个接口之一:Serializable// 这是一个标记接口,没有方法
    Externalizable//该接口方法需要实现,因此我们一般实现 Serializable 接口

序列化

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;

//演示 ObjectOutputStream 的使用, 完成数据的序列化
public class ObjectOutStream_ {
    public static void main(String[] args) throws IOException {
        //序列化后,保存的文件格式,不是纯文本,而是按照他的格式来保存
        String filePath = "d:\\date.txt";
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(filePath));

        //序列化数据到 d:\date.txt
        oos.writeInt(100);// int -> Integer (实现了 Serializable)
        oos.writeBoolean(true);// boolean -> Boolean (实现了 Serializable)
        oos.writeChar('a');// char -> Character (实现了 Serializable)
        oos.writeDouble(9.5);// double -> Double (实现了 Serializable)
        oos.writeUTF("帅哥");//String

        //关闭
        oos.close();

        System.out.println("数据保存完毕(序列化形式)");

    }
}

反序列化

import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;

public class ObjectInputStream_ {
    public static void main(String[] args) throws IOException {
        String filePath = "d:\\date.txt";

        ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(filePath));


        System.out.println(objectInputStream.readBoolean());
        System.out.println(objectInputStream.readDouble());
        objectInputStream.close();

        System.out.println("反序列化完毕");
    }
}

  • 对象流的注意事项
    1,读写顺序要一致
    2,要求序列化或反序列化对象,需要实现Serializable
    3,序列化的类中建议添加SerialVersionUID,为了提高版本的兼容性
    4,序列化对象时,默认将里面所有属性都进行序列化,但除了static或transient修饰的成员
    5,序列化对象时,要求里面属性的类型也需要实现序列化接口
    6,序列化具备可持续性,也就是如果某类已经实现了序列化,则它的所有子类也已经默认实现了序列化
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值