JAVA复习 Day22+Day23 IO流 +MYSQL

19 IO流

19.1文件

19.1.1概念

保存数据的地方
文件流
文件在程序中是以流的形式来操作的
在这里插入图片描述
流:数据在数据源(文件)和程序(内存)之间经历的路径
输入和输出都是针对于内存来说的,往内存内走的数据,是输入流,否则是输出流

19.1.2常用的文件操作

new File(String pathname)//根据路径构建一个File对象
new File(File parent ,String child)//根据父目录文件+子路径构建
new File(String parent ,String child)//根据父目录+子路径构建

createNewFile创建新文件

//方式一
 @Test
    public  void  create01(){
        String filepath="d:\\dan.txt";
        File file = new File(filepath);

        try {
            file.createNewFile();
            System.out.println("文件创建成功");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    //方式二
    //new File(File parent ,String child);
    //根据父目录加上子路径进行构建
@Test
    public  void  creat02(){
        File file = new File("d:\\");
        String filename ="news2.txt";
        File file1 = new File(file,filename);
        //在这里只是创建了File对象
        try {
            file1.createNewFile();
            //只有进行createNewFile()之后才能创建文件
            System.out.println("创建成功~");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

//方式三:new File(String parent ,String child)
    @Test
    public  void create03(){
        String dir ="d:\\";
        String  name="new3.txt";
        File file = new File(dir, name);
        try {
            file.createNewFile();
            System.out.println("创建成功!!!");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

获取文件的相关信息
getName、getAbsolutePath、length、exists 、isFile 、isDirectory 、getParent

 @Test
    public  void  info(){
        //先创建文件对象
        File file = new File("d:\\news2.txt");
        System.out.println("文件的名字"+file.getName());
        System.out.println("是否是文件"+file.isFile());
        System.out.println("绝对路径"+file.getAbsolutePath());
        System.out.println("父目录"+file.getParent());
        System.out.println("文件的大小"+file.length());
        System.out.println("是否是目录"+file.isDirectory());
    }

目录的操作和文件删除
mkdir创建一级目录,mkdirs创建多级目录delete删除空目录或文件
在针对目录的时候其实是也被当成了文件来进行的

 @Test
    public void m1(){
        String filepath ="d:\\news2.txt";
        File file = new File(filepath);
        if (file.exists()){
            if (file.delete()){
            //在这里file.delete()会返回一个布尔值
                System.out.println("文件删除成功"+filepath);
            }
            else{
                System.out.println("文件删除失败"+filepath);
            }
        }
        else{
            System.out.println("文件不存在!");
        }
    }
@Test
    public  void m3(){
        String  path="d:\\demo\\a";
        File file = new File(path);
        if (file.exists()){
            System.out.println("该目录存在");
        }
        else{
            if (file.mkdirs()){
            //多级目录的创建,返回的是一个布尔值
                System.out.println("创建成功"+path);
            }
            else{
                System.out.println("创建失败"+path);
            }
        }
    }

19.2IO流原理及流的分类

19.2.1IO流原理

I/O是非常实用的技术,用于处理数据传输,如读文件,写文件,网络通讯
JAVA程序中,对于数据的输入/输出操作以流的方式进行
JAVA.io包下提供了各种流类和接口,用以获取不同种类的数据,并通过方法输入或输出数据
在这里插入图片描述

19.2.2流的分类

按操作数据单位不同分为:字节流(8bit,它的好处是针对二进制的文件可以达到无损的效果)字符流(按字符,对应几个字节,文本文件较好)
按数据流的流向不同分为:输入流,输出流
按流的角色的不同分为:节点流,处理流/包装流
在这里插入图片描述
InputStream和OutputStream:都是抽象类,不能直接创建,只能通过实现子类来创建流对象
Reader和Writer也都是抽象类,不能直接创建

文件VS流
流可以理解为:我们买物品,物品通过快递发送给我们,而在运送的途中,经过快递小哥,快递小哥可以理解为流

19.2.3 IO流体系图——常用的类

InputStream:抽象类是所有类字节输入流的超类
常用的子类
FileInputStream:文件输入流
BufferedInputStream:缓冲字节输入流
ObjectInputStream:对象字节输入流

在这里插入图片描述

19.2.3.1FileInputStream介绍

构造方法

FileInputStream(File file)
通过打开与实际文件的连接创建一个 FileInputStream ,该文件由文件系统中的 File对象 file命名。
FileInputStream(FileDescriptor fdObj)
创建 FileInputStream通过使用文件描述符 fdObj ,其表示在文件系统中的现有连接到一个实际的文件。
FileInputStream(String name)
通过打开与实际文件的连接来创建一个 FileInputStream ,该文件由文件系统中的路径名 name命名。

**构造方法的网页参考
**https://www.matools.com/file/manual/jdk_api_1.8_google/java/io/FileInputStream.html
在这里插入图片描述

@Test
    public  void readfile(){
        String  filepath="d:\\dan.txt";
        int read =0;
        FileInputStream fileInputStream = null;
        try {
            //创建对象,用于读取文件
            fileInputStream = new FileInputStream(filepath);
            while((read = fileInputStream.read())!=-1){
                //当fileInputStream.read()不等于-1的时候,则就输出
                //数据的下一个字节,如果达到文件的末尾, -1
                System.out.println((char)read);
                //转换成char
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            //由于打开了文件,所以最后应当关闭文件流,释放资源
            //最后一定要抛出异常
            try {
                fileInputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    //注:针对字符的时候,最好不用字节流
//上面只有单个字符的读取,而下面的方法可以比上面个的方法更高效
public int read(byte[] b)
         throws IOException
从该输入流读取最多b.length字节的数据到字节数组。 此方法将阻塞,直到某些输入可用。
如果读取正常则返回实际读取的字节数
19.2.3.2FileOutputStream介绍
FileOutputStream(File file)
创建文件输出流以写入由指定的 File对象表示的文件。
FileOutputStream(File file, boolean append)
创建文件输出流以写入由指定的 File对象表示的文件。
FileOutputStream(FileDescriptor fdObj)
创建文件输出流以写入指定的文件描述符,表示与文件系统中实际文件的现有连接。
FileOutputStream(String name)
创建文件输出流以指定的名称写入文件。
FileOutputStream(String name, boolean append)
创建文件输出流以指定的名称写入文件。

在这里插入图片描述

 @Test
    public  void outfile(){
        String  filepath="d:\\dan1.txt";
        //创建一个对象设为空
        FileOutputStream fileOutputStream = null;
        try {
        //将文件的路径放入
            fileOutputStream = new FileOutputStream(filepath);
            fileOutputStream.write('a');
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                //释放资源,关闭文件
                fileOutputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

new FileOutputStream(filepath):此创建方式,当写入内容时,会覆盖原来的内容
new FileOutputStream(filepath,true)创建方式,当写入内容时,是追加到文件后面

19.2.3.3文件拷贝
public class copyfile {
    public static void main(String[] args) {
       //要完成文件拷贝
       //创建文件的输入流,将文件读入到程序
       //创建文件的输出流,将读取到的文件数据,写入到指定的文件
        FileInputStream fileInputStream =null;
        FileOutputStream fileOutputStream=null;
        String  filepath="d:\\dan1.txt";//源文件
        String  filepath1="d:\\dan3.txt";//要进行新文件的书写
        try {
            fileInputStream =new FileInputStream(filepath);
            fileOutputStream= new FileOutputStream(filepath1);
            byte [] buffer= new byte[1024];
            int readln=0;
            while ((readln =fileInputStream.read(buffer))!=-1){
            //注:这里是读取文件的内容,readln记录的是个数,如果为空了,则返回-1
                //读取到之后就写进去,边度边写
                fileOutputStream.write(buffer,0,readln);
                //边读边写的时候不能用其他方法,因为可能为9个,那么其他方法可能就会输出一个
                //一定要用这个
            }
            System.out.println("拷贝成功");
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (fileInputStream!=null){
                    fileInputStream.close();
                    //释放资源
                }
                if (fileOutputStream!=null){
                    fileOutputStream.close();
                    //释放资源
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
19.2.3.4FileReader和FileWriter介绍

它们两个是字符流
FileReader
new FileReader(File/String)
read:每次读取单个字符,返回该字符,如果到文件末尾返回-1
read(char[ ]):批量读取多个字符到数组,返回读取到的字符数,如果到文件末尾返回-1
new String(char []):将char[ ]转换成String
new String (char [ ],off,len):将char[ ]的指定部分转换成String
在这里插入图片描述
FileWriter
FileWriter(File /String)
覆盖模式,相当于流的指针在首端
FileWriter(File/String , boolean append)
追加模式,相当于流的指针在尾端
write(int):写入单个字符
write(char[ ]):写入指定数组
write(char[ ],off,len):写入指定数组的指定部分
write(String):写入整个字符串
write(String,off,len):写入字符串的指定部分
String类:toCharArray:将String转换成char[ ]
FileWriter使用后,必须要关闭(close)或者刷新(flush),否则写入不到指定的文件
在这里插入图片描述

19.3节点流和处理流

在这里插入图片描述
BufferedReader类中,有属性Reader,即可以封装一个节点流,该节点流可以是任意的,只要是Reader的子类即可
BufferedWriter类中,有Writer属性,即可以封装一个节点流,该节点流可以是任意的
在这里插入图片描述

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

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

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

19.3.2模拟处理流设计模式(代码模拟)

public  abstract class reader01 {
    //抽象类Reader
    public    void readfile(){};
    public  void  readString(){};
    
}

class FileReader_ extends  reader01{
    public  void  readfile(){
        System.out.println("对文件进行读取....");
    }
    //文件
}

class  StrinfReader_ extends  reader01{
    public  void readString(){
        System.out.println("读取字符串.....");
    }
    //字符
}
class BufferedReader_ extends  reader01{
    private  reader01 reader011;//属性是reader01的类型
    public  BufferedReader_(reader01 reader0111){
        this.reader011=reader0111;
        
    }
    //进行功能扩展
    public  void readfilenum(int num){
        for (int i=0;i<num;i++){
            reader011.readfile();
        }
    }
}

19.3.3BufferedReader和BufferedWrite

它们属于字符流,是按照字符来读取数据的,关闭处理流时,只需要关闭外层流即可
在关闭包装流的时候,底层会自动关闭字节流

BufferedReader读取文本文件
public class breader {
    public static void main(String[] args) throws Exception {

        String filepath="d:\\dan1.txt";
        BufferedReader bufferedReader = new BufferedReader(new FileReader(filepath));
        String  line;
        //按行读取
        //当返回一个空是则表示流的末尾
        while((line=bufferedReader.readLine())!=null){
            System.out.println(line);
        }
        //关闭流
        //只需要关闭BufferedReader,因为底层会自动的去关闭节点流
        bufferedReader.close();
    }

}
BufferedWrite
public class breader {
    public static void main(String[] args) throws Exception {

        String filepath="d:\\dan89.txt";
        BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(filepath));
        bufferedWriter.write("小明你好!");
        bufferedWriter.newLine();
        bufferedWriter.write("小明你好!");
        bufferedWriter.close();
    }
}

如果想要以追加的方式写入,只需要添加一个节点流的参数,因为包装流并没有提供一个方法让其追加

19.3.4BufferedInputStream和BufferedOutputStream

按照字节来处理的
在这里插入图片描述
在这里插入图片描述

19.3.5对象处理流ObjectInputStream和ObjectOutputStream

依旧是处理流
序列化和反序列化
序列化就是保存数据时,保存数据的值和数据类型
反序列化就是回复数据时,恢复数据的值和数据类型
需要让某个对象支持序列化机制,则必须让其类是可序列化的,为了让某个类是可序列化的,该类必须实现如下两个接口:

Serializable://这是一个标记接口
Externalizable://该接口有方法需要实现,一般需要实现上面的接口

在这里插入图片描述

序列化
public class outputobj {
    public static void main(String[] args) throws  Exception{
        //序列化之后,保存的文件格式,不是存文本,而是按照它的格式来保存
         String filepath="d:\\dan1.txt";
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(filepath));

        //序列化数据到上面的文件中
        oos.write(100);//int ->Integer(实现了Serializable的接口)
        oos.writeBoolean(true);//boolean ->Boolean (实现了Serializable接口)
        oos.writeChar('a');//char -> Character (实现类Serializable接口)
        oos.writeUTF("小明在努力");//String
        oos.writeObject(new Dog("小花",34));
        oos.close();
        System.out.println("数据保存完毕,序列化形式");


    }
}
//如果需要序列化某个对象则必须实现Serializable
class  Dog implements Serializable {
    private  String  name;
    private  int age;

    public Dog(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}
反序列化
这里如果要是不再一个包中,需要重新写一个类
public class Objectstream {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        String filepath="d:\\dan1.txt";
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(filepath));

        //读取顺序需要和保存数(序列化的顺序一致)
        System.out.println(ois.readInt());
        System.out.println(ois.readBoolean());
        System.out.println(ois.readChar());
        System.out.println(ois.readUTF());
        Object o =ois.readObject();
        System.out.println("运行类型="+o.getClass());
        //关闭外层流即可
        ois.close();
    }
}
class  Dog implements Serializable {
    private  String  name;
    private  int age;

    public Dog(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Dog{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

19.3.5对象处理流的注意事项和细节

读写顺序要一致
要求实现序列化或反序列化对象,需要实现Serializable
序列化的类中建议添加SerialVersionUID,为了提高版本的兼容性
序列化对象时,默认将里面所有属性都进行序列化但除了static或transient修饰的成员
序列化对象时,要求里面属性的类型也需要是实现序列化接口
序列化具备可继承性,也就是说如果某类已经实现了序列化,则它的所有子类也已经默认实现了序列化

19.4输入流和输出流

在这里插入图片描述
System.out.println(System.in.getClass())
//System.in编译类型为InputStream
//System.in运行类型为BufferedInputStream
//表示的是标准输入
//System.out编译类型为PrintStream
//System.out运行类型为PrintStream
//表示标准输出显示器

19.4.1转换流 InputStreamReader和OutputStreamWriter

将字节流转换为字符流
字节流可以指定编码方式,再转换成字符流
在这里插入图片描述
InputStreamReader:Reader的子类,可以将 InputStream(字节流)包装成Reader(字符流)
OutputStreamWriter:Writer的子类,实现将OutputStream(字节流)包装成Writer(字符流)
可以在使用时指定编码格式

19.4.2打印流PrintStream和PrintWrite

打印只有输出流,没有输入流
PrintStream字节流
在这里插入图片描述

public class print {
    public static void main(String[] args) throws FileNotFoundException {

        PrintStream out= System.out;
        out.println("join,hello");
        System.setOut(new PrintStream("d:\\dan1.txt"));
        System.out.println("hello");

    }
}

PrintWrite字符流
在这里插入图片描述

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

        PrintWriter printWriter = new PrintWriter(System.out);
        printWriter.println("hi,北京你好~");
        printWriter.close();
        //FileWriter也是一样的必须要进行刷新或关闭
    }

}

19.5Properties类

专门用于读取配置文件的集合类
配置文件的格式:
键=值
键=值
键值对不需要有空格,值不需要引号括起来,默认类型时String

19.5.1常用方法

load:加载配置文件的键值对Properties对象
list:将数据显示到指定设备
getProperty(key):根据键获取值
setProperty(key,value):设置键值对到Properties对象
store:将Properties中的键值对存储到配置文件,在idea中,保存信息到配置文件,如果含有中文,会存储unicode码

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值