JavaIO流(韩)

JavaIO流(韩)

文件

文件:文件是保存数据的地方,比如大家经常使用的word文档、txt文档、excel文件…都是文件。它既可以是一张图片,也可以是一个视频,一段声音

文件流:文件在程序中是以流的形式来操作的,就是数据在数据源(文件)和程序(内存)之间经历的路径

输入流:数据从数据源(文件)到程序(内存)的路径

输出流:数据从程序(内存)到数据源(文件)的路径

注意:输入/输出流是相对内存来说的

在这里插入图片描述

常见的文件操作

创建文件
new File(String pathname)//根据路径构建一个File对象
new File(File parent,String child)//根据父目录文件+子路径构建
new File(String parent,String child)//根据父目录+子路径构建
createNewFile 创建新文件
public class FileCreate {
    public static void main(String[] args) {
        createFile01("D:/你好01.txt");
        createFile02(new File("D:/"),"你好02.txt");
        createFile03("D:/","你好03.txt");
    }
    //方式一:String path//根据路径构建一个File对象
    public static void createFile01(String path){
        //这里的file对象,在Java程序当中,只是一个对象,
        //只有执行了createNewFile()方法,才会真正的,在磁盘创建该文件
        File file = new File(path);
        try {
            file.createNewFile();
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println("文件创建成功01");
    }

    //方式二:File parent,String path//根据父目录文件+子路径构建
    public static void createFile02(File parent,String path){
        File file = new File(parent, path);
        try {
            file.createNewFile();
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println("文件创建成功02");
    }

    //方式三:String parent,String path//根据父目录+子路径构建
    public static void createFile03(String parent,String path){
        File file = new File(parent, path);
        try {
            file.createNewFile();
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println("文件创建成功03");
    }
}
获取文件的相关信息
  • getName
  • getAbsolutePath
  • getParent
  • length
  • exists
  • isFile
  • isDirectory
public class FileInformation {
    public static void main(String[] args) {
        info(new File("D:/你好01.txt"));
    }

    //获取文件的信息
    public static void info(File file){
        //调用相应的方法,得到相应的信息
        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());
        System.out.println("问否为文件:" + file.isFile());
        System.out.println("是否为目录:" + file.isDirectory());
    }
}
目录的操作和文件的删除
  • mkdir创建一级目录
  • mkdirs创建多级目录
  • delete删除空目录或文件
public class Directory {
    public static void main(String[] args) {
        File file = new File("D:/你好02.txt");
        //在java编程中,目录也被当作是文件(一种特殊的文件)
        File directory1 = new File("D:/广州好迪");
        File directory2 = new File("D:/我好/大家好");
        //判断文件是否存在,存在则删除
        if (file.exists()){
            if (file.delete())
                System.out.println("删除成功");
            else
                System.out.println("删除失败");
        }else{
            System.out.println("文件不存在");
        }
        //判断目录是否存在,不存在则创建
        //在java编程中,目录也被当作是文件(一种特殊的文件)
        if (directory1.exists() == false){
            //一次只能创建一个目录,如果在目录有多个不存在,则创建失败
            directory1.mkdir();
            System.out.println("目录创建成功");
        }else{
            System.out.println("目录存在");
            //directory1.delete();删除空目录
        }

        //判断目录是否存在,不存在则创建
        //在java编程中,目录也被当作是文件(一种特殊的文件)
        if (directory1.exists() == false){
            //一次可创建多个目录,如果在目录有多个不存在,则创建所有不存在目录
            directory2.mkdirs();
            System.out.println("目录创建成功");
        }else{
            System.out.println("目录存在");
        }
    }
}

IO流原理和流的分类

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

流的分类

  • 按操作数据单位不同分为:字节流(8 bit)二进制文件、字符流(按字符)文本文件
  • 按数据流的流向不同分为:输入流,输出流
  • 按流的角色的不同分为:节点流,处理流/包装流

在这里插入图片描述

  1. java的io流共涉及40多个类,实际上非常规则,都是从如上四个抽象基类派生的
  2. 由这四个类派生出来的子类名称都是以其父类名作为子类名后缀

流和文件的关系:文件(相当于一个快递站),文件里面的数据(相当于快递站里面的快递),流相当于一个快递员,内存(程序相当于一个用户)。当内存需要读取磁盘里面的文件的数据时,就相当于用户需要拿到自己快递,流(快递员)就是这个获取的工具

常用的流

InputStream:字节输入流,Reader:字符输入流

InputStream抽象类是所有字节输入流类的超类

InputStream常用的子类

  1. FileInputStream:文件输入流
  2. BufferedInputStream:缓冲字节输入流
  3. ObjectInputStream:对象字节输入流
FileInputStream:文件输入流

要求:使用FileInputStream读取hello.txt文件,并将文件内容显示到控制台

public class FileInputStream01 {
    public static void main(String[] args) {
        readFile02();

    }

    //读取文件的方式一:read()方法
    public static void readFile01(){
        String path = "D:/hello.txt";
        int readResult = 0;
        FileInputStream fis = null;
        try {
            //创建FileInputStream对象,用于读取"D:/hello.txt"文件
            fis = new FileInputStream(path);
            //read()方法,表示从该流中读取一个字节的数据,如果没有输入可用,此方法将阻止
            //read()方法,返回 -1 表示读取完毕
            //read()方法,一次只能读取一个字节数据,所以采用循环的方式读取
            //因为一个汉字占有(三个字节),所以按这种方式读取汉字会出现乱码现象
            //单个字节的读取,效率太慢,所以采用读取字节数组的方式
            while ((readResult = fis.read()) != -1){
                System.out.print((char)readResult);//转成字符显示
            }

        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            //关闭文件流,释放资源
            try {
                fis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    //读取文件的方式二:read(byte[] b)
    public static void readFile02(){
        String path = "D:/hello.txt";
        int readLen = 0;
        FileInputStream fis = null;
        //字节数组
        byte[] buffer = new byte[9];//一次读取9个字节
        try {
            //创建FileInputStream对象,用于读取"D:/hello.txt"文件
            fis = new FileInputStream(path);
            //fis.read(buffer)返回实际一次读取到字节总数
            //如果返回 -1 表示读取完毕
            while ((readLen = fis.read(buffer)) != -1){
                System.out.print(new String(buffer,0,readLen));//转成字符串显示
                //0,readLen 这里为什么填readLen
                //因为,当读取到最后时,可能不够这么多,覆盖上一次的byte[]数组之后可能有上一次读取的数据存留
                //但是,只读取这次读取到字节,可避免这个问题
            }

        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            //关闭文件流,释放资源
            try {
                fis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
FileReader:文件字符输入流

FileReader和FileWriter是字符流,即按照字符来操作io

FileReader的相关方法

  1. new FileReader(File/String):创建流
  2. read():每次读取单个字符,返回该字符,如果到文件末尾返回-1
  3. read(char[]):批量读取多个字符到数组,返回读取到的字符输,如果到文件末尾返回-1

相关API

  1. new String(char[]):将char[]数组转换为String
  2. new Strilng(char[] ,off,len):将char[]数组的指定部分转换为String

要求:使用FileReader从story.txt读取内容,并显示

public class FileReader01 {
    public static void main(String[] args) {
        read01();
        //read02();
    }

    //单个读取
    public static void read01(){
        String path = "D:/a.txt";
        FileReader fr = null;
        int len = 0;
        try {
            fr = new FileReader(path);
            while ((len = fr.read()) != -1) {
                System.out.println((char) len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fr != null) {
                try {
                    fr.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    //循环读取
    public static void read02(){
        String path = "D:/a.txt";
        FileReader fr = null;
        char[] chars = new char[1024];
        int len = 0;
        try {
            fr = new FileReader(path);
            while ((len = fr.read(chars)) != -1) {
                System.out.println(new String(chars,0,len));
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fr != null) {
                try {
                    fr.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

OutputStream:字节输出流,Writer:字符输出流

FileOutputStream:文件输出流

要求:使用FileOutputStream在 a.txt 文件,中写入“hello,world”,提示:如果文件不存在,会创建文件(注意:前提是目录已经存在)

public class FileOutputStream01 {
    public static void main(String[] args) {
        writeFile01();
        //new FileOutputStream(path)流的创建方式是覆盖形的
        //如果想要在末尾加上字符,需要使用下面的创建方式
        //new FileOutputStream(path,true)

    }

    public static void writeFile01(){
        String path = "D:/a.txt";
        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream(path);
            //写入一个字节
            //fos.write('a');//char--自动-->int
            //写入一个字符串
            //String str = "hello,world!";
            //str.getBytes(),将字符串转换为一个byte[]数组
            //fos.write(str.getBytes());

            String str = "hsp,world!";
            fos.write(str.getBytes(),0,3);//可指定写入哪些字节

        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                fos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
FileWriter:文件字符输出流

FileWriter常用方法

  1. new FileWriter(File/String):覆盖模式创建流
  2. new FileWriter(File/String,true):追加模式创建流
  3. write(int):写入单个字符
  4. write(char[]):写入指定数组
  5. write(char[],off,len):写入指定数组的指定部分
  6. write(string):写入整个字符串
  7. write(string,off,len):写入字符串的指定部分

相关API

String类:toCharArray:将String转换成为char[]

注意:FileWrite使用后,必须要关闭(close)或者刷新(flush),否则写入不到指定的文件!

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

    }

    public static void write(){
        String path = "D:/a.txt";
        FileWriter fw = null;
        String str = "风雨之后见彩虹";
        try {
            fw = new FileWriter(path,true);
            //fw.write('h');//写入单个字符
            //fw.write(str.toCharArray());//写入char数组
            //fw.write(str.toCharArray(),0,4);//写入char数组
            //fw.write(str);//写入字符串
            fw.write(str,0,3);//写入字符串的指定部分
            //对于FileWriter 一定要刷新或者关闭流,不然数据写入不到文件中
            fw.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if (fw != null) {
                try {
                    fw.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

将输入流和输出流综合应用,完成文件的拷贝

要求:编程完成图片的拷贝(FileInputStream/FileOutputStream)

public class CopyFile01 {
    public static void main(String[] args) {
        copy();
    }

    public static void copy(){
        String srcPath = "D:/5.jpg";//源文件
        String destPath = "D:/5复制.jpg";//目标文件
        FileInputStream fis = null;
        FileOutputStream fos = null;
        try {
            //创建文件输入流
            fis = new FileInputStream(srcPath);
            //创建文件输出流
            fos = new FileOutputStream(destPath, true);
            //创建输入的字节数组
            byte[] buffer = new byte[1024];
            //定义每次读取的字节总数标识
            int len = 0;
            //循环读取、写出
            while ((len = fis.read(buffer)) != -1){
                fos.write(buffer,0,len);//一定要这样写出
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally{
            try {
                //加上一个判断 流 是否等于空
                if (fos != null) {
                    fos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (fis != null) {
                    fis.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
使用输入流和输出流完成文件的拷贝(FileReader/FileWriter)
public class CopyFile02 {
    public static void main(String[] args) {
        copy2();
    }

    public static void copy2(){
        String srcPath = "D:/a.txt";
        String destPath = "D:/b.txt";
        FileReader fr = null;
        FileWriter fw = null;
        try {
            fr = new FileReader(srcPath);
            fw = new FileWriter(destPath);
            char[] chars = new char[1024];
            int len = 0;
            while ((len = fr.read(chars)) != -1){
                fw.write(chars,0,len);
            }
            fw.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if (fw != null) {
                try {
                    //fw.close() == fw.flush() + fw.close()
                    fw.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (fr != null) {
                try {
                    fr.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }
}

节点流和处理流

节点流可以从一个特定的数据源读写数据,如FileReader、FileWriter

在这里插入图片描述

处理流(也叫包装流)是“连接”在已存在的流(节点流或处理流)之上,为程序提供更为强大的读写功能,如BufferedReader、BufferedWriter

在这里插入图片描述

节点流是针对数据源来说的,处理流(包装流)是针对流来说的

在这里插入图片描述

处理流中有抽象基类属性,即可以封装一个节点流,该节点流可以是对应的任意抽象基类的子类,如:BufferedReader/BufferedWriter类中,有属性Reader/Writer,即可以封装一个节点流,该节点流可以是对应的任意Reader/Writer子类

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

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

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

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

处理流-BufferedReader和BufferedWriter

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

public class BufferedReader01 {
    public static void main(String[] args) {
        BufferedReader br = null;
        try {
            br = new BufferedReader(new FileReader("D:/a.txt"));
            /*char[] chars = new char[1024];
            int len = 0;
            //按字符数读取
            while ((len = br.read(chars)) != -1){
                System.out.println(new String(chars,0,len));
            }*/
            String line ;
            //br.readLine()表示按行读取,返回null时,表示读取完毕
            while ((line = br.readLine()) != null){
                System.out.println(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if (br != null) {
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
public class BufferedWriter01 {
    public static void main(String[] args) {
        String str = "hsp教育";
        BufferedWriter bw = null;
        try {
            bw = new BufferedWriter(new FileWriter("D:/a.txt",true));
            bw.write(str);//以字符串形式写入
            bw.newLine();//插入一个换行符
            bw.write(str.toCharArray());//以char[]数组形式写入
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if (bw != null) {
                try {
                    bw.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

复制文件

public class CopyFile03 {
    public static void main(String[] args) {
        BufferedReader br = null;
        BufferedWriter bw = null;
        try {
            br = new BufferedReader(new FileReader("D:/a.txt"));
            bw = new BufferedWriter(new FileWriter("D:/c.txt"));
            char[] chars = new char[1024];
            int len = 0;
            while ((len = br.read(chars)) != -1){
                bw.write(chars,0,len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if (bw != null) {
                try {
                    bw.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (br != null) {
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

复制图片

public class CopyFile04 {
    public static void main(String[] args) {
        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;
        try {
            bis = new BufferedInputStream(new FileInputStream("D:/5.jpg"));
            bos = new BufferedOutputStream(new FileOutputStream("D:/6.jpg"));
            byte[] buffer = new byte[1024];
            int len = 0;
            while ((len = bis.read(buffer)) != -1){
                bos.write(buffer,0,len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if (bos != null) {
                try {
                    bos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (bis != null) {
                try {
                    bis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }
}

处理流:BufferedInputStream和BufferedOutputStream

BufferedInputStream和BufferedOutputStream的用法和BufferedReader和BufferedWriter是一样的,只不过中间使用的流不一样

处理流:ObjectInputStream和ObjectOutputStream

看一个需求:

将int num = 100这个数据保存到文件中,注意不是100数字,而是int 100,并且,能够从文件中直接恢复int 100

将Dog dog = new Dog(“小红”,3)这个dog对象报错到文件中,并且能够从文件中恢复,

上面的要求就是在保存数据时,保存数据的值和数据类型

序列化和反序列化

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

两个处理流的功能:

  • 提供了对基本数据类型或对象类型的序列化和反序列化的方法
  • ObjectOutputStream提供了序列化功能
  • ObjectInputStream提供了反序列功能

应用案例:使用ObjectOutputStream 序列化 基本数据类型和 一个 Dog对象(name,age),并保存到 data.dat 文件中

**
 * 应用案例:使用ObjectOutputStream 序列化 基本数据类型和 一个 Dog对象(name,age),
 * 并保存到 data.dat 文件中
 * 需要注意:序列化会将类的包名也一起写入文件中,所以序列化和反序列化时,应该是同一个包中的类
 * @author cyg
 * 
 */
public class ObjectOutputStream01 {
    public static void main(String[] args) {
        ObjectOutputStream oos = null;
        try {
            oos = new ObjectOutputStream(new FileOutputStream("D:/data.dat"));
            //写入对象(序列化)
            //注意:100在保存时,以Integer进行装箱 Integer实现了Serializable
            oos.writeInt(100);//int
            oos.writeBoolean(true);//boolean
            oos.writeChar('a');//char
            oos.writeDouble(9.5);//double
            oos.writeUTF("张三丰");//写入整个字符串,string
            //dog实现了serializable
            oos.writeObject(new Dog("旺财",3));//序列化对象
            oos.writeObject(new Dog("大黄",2));//序列化对象
            oos.writeObject(new Dog("天天",1));//序列化对象
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if (oos != null) {
                try {
                    oos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }
}

/**
 * 使用ObjectInputStream 对data.dat文件进行反序列化操作,对数据进行恢复
 * @author cyg
 * 
 */
public class ObjectInputStream01 {
    public static void main(String[] args) {
        ObjectInputStream ois = null;
        try {
            ois = new ObjectInputStream(new FileInputStream("D:/data.dat"));
            //注意读取的顺序,读取的顺序要和保存的顺序一致
            System.out.println(ois.readInt());
            System.out.println(ois.readBoolean());
            System.out.println(ois.readChar());
            System.out.println(ois.readDouble());
            System.out.println(ois.readUTF());

            /*Object obj = ois.readObject();
            //要使用dog的方法需要向下转型
            //需要我们将Dog的定义,拷贝到可以应用的地方,或者让它是公用的
            Dog dog = (Dog)obj;
            //运行类型
            dog.getClass();*/

            System.out.println(ois.readObject());
            System.out.println(ois.readObject());
            System.out.println(ois.readObject());
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }finally {
            if (ois != null) {
                try {
                    ois.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

/**
 * 为了dog可以序列化,需要让它实现Serializable
 * @author cyg
 * 
 */
public class Dog implements Serializable {
    private String name;
    private int 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 Dog(String name, int age) {
        this.name = name;
        this.age = age;
    }

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

注意事项和细节说明:

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

标准输入输出流

System.in 标准输入流 ,编译类型:InputStream ,运行类型:BufferedInputStream,默认设备:键盘

System.out 标准输入流 ,编译/运行类型:PrintStream ,默认设备:显示器

转换流:字节流->字符流,字符流->字节流

为什么需要转换流:文件乱码问题

InputStreamReader和OutputStreamWriter

介绍:

  1. InputStreamReader:Reader的子类,实现将InputStream(字节流)包装成Reader(字符流)
  2. OutputStreamWriter:Writer的子类,实现将OutputStream(字节流)包装成Writer(字符流)
  3. 当处理纯文本数据时,如果使用字符流效率更高,并且可以有效的解决中文问题,所以建议将字节流传唤成字符流
  4. 可以在使用时指定编码格式(比如:utf-8,gbk等等)
看一个中文乱码问题(默认是utf-8,如果文件的编码改变会出现乱码问题)
public class InputStreamReader01 {
    public static void main(String[] args) {
        InputStreamReader isr = null;
        BufferedReader br = null;
        try {
            //将字节流 FileInputStream 转换为 InputStreamReader 字符流
            //同时指定了编码格式
            isr = new InputStreamReader(new FileInputStream("D:/a.txt"),"utf-8");
            //将 InputStreamReader 放入到 BufferedReader 中
            //包装了两次
            br = new BufferedReader(isr);
            char[] chars = new char[1024];
            int len = 0;
            while ((len = br.read(chars)) != -1){
                System.out.print(new String(chars,0,len));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if (br != null) {
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
public class OutputStreamWriter01 {
    public static void main(String[] args) {
        OutputStreamWriter osw = null;
        BufferedWriter bw = null;
        try {
            //utf8 == utf-8
            osw = new OutputStreamWriter(new FileOutputStream("D:/a.txt",true),"gbk");
            bw = new BufferedWriter(osw);
            bw.write("韩顺平教育");
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if (bw != null) {
                try {
                    bw.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

打印流

PrintStream和PrintWriter

注意:打印流只有输出流,没有输入流

字节打印流 本质还是输出流
public class PrintStream01 {
    public static void main(String[] args) {

        PrintStream out = System.out;
        //在默认情况下,PrintStream 输出数据的位置是 标准输出,即显示器
        //out.println("hello");
        try {
            //下面两种方式的本质是一样,
            //out.println()的底层还是调用out.write()
            //所以我们可以直接调用 write() 进行打印/输出
            out.println("hello");
            out.write("hsp".getBytes());

            //可以修改打印流输出的 位置/设备
            //修改到"D:/b.txt"
            System.setOut(new PrintStream("D:/b.txt"));
            System.out.println("hello,hsp教育");

        } catch (IOException e) {
            e.printStackTrace();
        }
        out.close();

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

        PrintStream ps = System.out;
        PrintWriter printWrite = new PrintWriter(ps);
        printWrite.print("北京,你好");
        //close()才是真正写数据的地方 = flush() + close()
        printWrite.close();//一定要有,不然写不进去


        PrintWriter pw = null;
        try {
            pw = new PrintWriter(new FileWriter("D:/b.txt"));
            pw.write("北京,你好");
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if (pw != null) {
                pw.close();
            }
        }
    }
}

Properties类

看一个需求:

如下一个配置文件 mysql.properties

ip = 192.168.0.13
user = root
pwd = 12345

请问编程读取ip、user、pwd的值是多少

分析

  1. 传统的方法
  2. 使用Properties类可以方便实现
public class Properties01 {
    public static void main(String[] args) {
        FileReader fr = null;
        BufferedReader br = null;
        try {
            fr = new FileReader("src/mysql.properties");
            /*char[] chars = new char[1024];
            int len = 0;
            while ((len = fr.read(chars)) != -1){
                System.out.println(new String(chars,0,len));
            }*/

            br = new BufferedReader(fr);
            String lenLine ;
            while ((lenLine = br.readLine()) != null){
                //循环一次分一次   
                String[] split = lenLine.split("=");
                System.out.println(split[0] + ":" + split[1]);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            /*if (fr != null) {
                try {
                    fr.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }*/
            if (br != null) {
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

基本介绍

  1. 专门用于读取配置文件的集合类,配置文件的格式:键=值
  2. 注意:键值对不需要空格,值不需要用引号起来,默认类型是String

Properties的常见方法

  1. load:加载配置文件的键值对到Properties对象
  2. list:将数据显示到指定设备
  3. getProperty(key):根据键获取值
  4. setProperty(key,value):设置键值对到Properties对象
  5. store:将Properties中的键值对存储到配置文件,在idea中,保存信息到配置文件,如果含有中文,会存储为unicode码
public class Properties02 {
    public static void main(String[] args) {
        //使用Properties类来读取 mysql.properties文件

        //创建Properties对象
        Properties properties = new Properties();
        try {
            //加载指定文件
            properties.load(new FileReader("src/mysql.properties"));
            //将k-v显示控制台
            properties.list(System.out);
            //根据键获取值
            String user = properties.getProperty("user");
            System.out.println(user);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
public class Properties03 {
    public static void main(String[] args) {
        //使用Properties类来创建 mysql2.properties文件
        //如果该文件没有这个key,就是创建
        //如果有这个key,就是修改

        //创建Properties对象
        Properties properties = new Properties();
        //创建
        properties.setProperty("charset","utf8");
        //注意:保存中文时,是保存unicode码值,使用字节流才是unicode码值,字符流不是
        properties.setProperty("user","汤姆");
        properties.setProperty("pwd","88888");
        //将键值对存储文件中
        try {
            //comments形参表示注释,一般可以写null
            properties.store(new FileWriter("src/mysql2.properties"),null);
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

练习

/**
 * 在判断d盘下是否有文件夹mytemp,如果没有就创建,并在该目录下创建hello.txt
 *如果该文件存在,提示该文件存在,就不要重复创建了
 * 并且在文件中写入hello,world
 * @author cyg
 * 
 */
public class HomeWork01 {
    public static void main(String[] args) {
        File file = new File("D:/mytemp");
        FileWriter fw = null;
        if (file.exists()){
            File file1 = new File("D:/mytemp/hello.txt");
            if (file1.exists()){
                System.out.println("该文件已存在");
            }else{
                try {
                    file1.createNewFile();
                    System.out.println("文件已创建");
                    fw = new FileWriter("D:/mytemp/hello.txt");
                    fw.write("hello,world");
                    fw.flush();
                } catch (IOException e) {
                    e.printStackTrace();
                }finally {
                    if (fw != null) {
                        try {
                            fw.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }else{
            System.out.println("文件夹不存在");
            file.mkdir();
            System.out.println("文件夹已创建");
        }
    }
}
/**
 * 使用BufferedReader读取一个文本文件,为每行加上行号
 * 要连同内容一起输到屏幕上
 * @author cyg
 * 
 */
public class HomeWork02 {
    public static void main(String[] args) {
        BufferedReader br = null;
        int i = 1;
        try {
            br = new BufferedReader(new FileReader("D:/b.txt"));
            String lenLine;
            while ((lenLine = br.readLine()) != null){
                System.out.println("第" + i++ + "行:" + lenLine);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}
/**
 * 编写一个dog.properties,name=tom,age=5,color=red
 * 编写Dog类(name,age,color)创建一个dog对象,读取dog.properties
 * 用相应的内容完成属性初始化,并输出
 * 将Dog对象序列化到dog.dat文件中
 * @author cyg
 * 
 */
public class HomeWork03 {
    public static void main(String[] args) {
        Properties properties = new Properties();
        ObjectOutputStream oos = null;

        properties.setProperty("name","tom");
        properties.setProperty("age","5");
        properties.setProperty("color","red");

        try {
            properties.store(new FileWriter("src/dog.properties"),null);
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println("文件创建成功");
        try {
            properties.load(new FileReader("src/dog.properties"));
        } catch (IOException e) {
            e.printStackTrace();
        }

        String name = properties.getProperty("name");
        String age = properties.getProperty("age");
        String color = properties.getProperty("color");
        Dog dog = new Dog(name, Integer.parseInt(age), color);

        try {
            oos = new ObjectOutputStream(new FileOutputStream("D:/dog.dat"));
            oos.writeObject(dog);
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if (oos == null) {
                try {
                    oos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        System.out.println(dog);
        HomeWork03 h3 = new HomeWork03();
        h3.m1();


    }

    //反序列化方法
    public void m1(){
        ObjectInputStream ois = null;
        try {
            ois = new ObjectInputStream(new FileInputStream("D:/dog.dat"));
            Object o = ois.readObject();
            Dog dog = (Dog) o;
            System.out.println(o);
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }finally {
            if (ois != null) {
                try {
                    ois.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
class Dog implements Serializable {
    private String name;
    private int age;
    private String color;

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

    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 String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    public Dog(String name, int age, String color) {
        this.name = name;
        this.age = age;
        this.color = color;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值