0
点赞
收藏
分享

微信扫一扫

【Java基础学习笔记】IO流

waaagh 2022-04-18 阅读 81
java

目录

IO流

文件

  1. 文件流:
    文件在程序中是以流的形式来操作的
    流:数据在数据源(文件)和程序(内存)之间经历的路径
    输入流:数据从数据源到程序的路径
    输出流:数据从程序到数据源的路径

  2. 常用的文件操作:
    (1)创建文件

    public class FileCreate {
        //1.new File(String pathname)根据路径创建文件
        @Test
        public void create1(){
            String filePath = "d:\\news1.txt";
            File file = new File(filePath);
            try {
                file.createNewFile();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        //2.new File(File parent,String child)根据父目录文件+子路径创建
        @Test
        public void create2(){
            File parentFile = new File("d:\\");
            String fileName = "news2.txt";
            File file2 = new File(parentFile, fileName);
            try {
                file2.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        //3.new File(String parent,String child)根据父目录+子路径创建
        @Test
        public void create3() {
            String parentName = "d:\\";
            String childName = "news3.txt";
            File file = new File(parentName, childName);
            try {
                file.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    

    (2)其他操作

    public class FileInformation {
        //获取文件信息
        @Test
        public void info(){
            //先创建文件对象
            File file = new File("d:\\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());
            System.out.println("是否是一个文件=" + file.isFile());
            System.out.println("是否是是一个目录=" + file.isDirectory());
        }
    }
    

    (3)目录操作

    public class Directory {
        //判断d:\\news1.txt是否存在,如果存在就删除
        @Test
        public void m1(){
            String filePath = "d:\\news1.txt";
            File file = new File(filePath);
            if(file.exists()){
                if(file.delete()){
                    System.out.println("删除成功");
                }else {
                    System.out.println("删除失败");
                }
            }else {
                System.out.println("文件不存在");
            }
        }
        //判断D:\\demo02 即目录是否存在,如果存在就删除
        @Test
        public void m2(){
            String directoryPath = "D:\\demo02";
            File dir = new File(directoryPath);
            if(dir.exists()){
                if(dir.delete()){
                    System.out.println("删除成功");
                }else {
                    System.out.println("删除失败");
                }
            }else {
                System.out.println("目录不存在");
            }
        }
        //判断D:\\demo\\a\\b\\c 目录是否存在,如果存在就提示已存在,否则就创建
        @Test
        public void m3(){
            String directoryPath = "D:\\demo\\a\\b\\c";
            File dic = new File(directoryPath);
            if(dic.exists()){
                System.out.println("该目录存在");
            }else {
                if(dic.mkdirs()){
                    System.out.println("创建成功");
                }else {
                    System.out.println("创建失败");
                }
            }
        }
    }
    

IO流基本介绍

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

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

    (抽象基类))字节流字符流
    输入流InputStreamReader
    输出流OutputStreamWriter

    注:Java的 IO 流共涉及40多个类,都是从如上4个抽象基类派生的;由这四个类派生出来的子类名称都是以其父类名作为子类名后缀

字节流

  1. 字节流常用的子类:
    FileInputStream:文件输入流
    FileOutputStream:文件输出流
    BufferedInputStream(是FilterInputStream的子类,FilterInputStream是InputStream的子类):缓冲字节输入流
    ObjectInputStream:对象字节输入流

  2. FileInputStream

    /**
     * 演示FileInputStream的使用
     * 字节输入流  文件 --> 程序
     */
    public class FileInputStream_ {
        /**
         * 演示读取文件
         * 单个字节读取,效率低
         */
        @Test
        public void readFile01() {
            String filePath = "d:\\hello.txt";
            FileInputStream fileInputStream = null;
            int readData = 0;
            try {
                //创建 FileInputStream 对象,用于读取文件
                fileInputStream = new FileInputStream(filePath);
                //返回-1,表示读取完毕
                while ((readData = fileInputStream.read()) != -1) {
                    System.out.print((char) readData);
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                //关闭文件流,释放资源
                try {
                    fileInputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    
        /**
         * 使用read(byte[] b)读取,提高效率
         */
        @Test
        public void readFile02() {
            String filePath = "d:\\hello.txt";
            FileInputStream fileInputStream = null;
            //定义一个字节数组
            byte[] buf = new byte[8];//一次读8个
            int readLen = 0;
            try {
                //创建 FileInputStream 对象,用于读取文件
                fileInputStream = new FileInputStream(filePath);
                while ((readLen = fileInputStream.read(buf)) != -1) {
                    System.out.print(new String(buf, 0, readLen));
    
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                //关闭文件流,释放资源
                try {
                    fileInputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    
  3. FileOututStream

    public class FileOutputStream_ {
       /**
         * 将数据写到文件中
         * 如果文件不存在,则创建该文件
         */
        @Test
        public void writeFile() {
            String filePath = "d:\\a.txt";
            FileOutputStream fileOutputStream = null;
            try {
                //使用这种方式,写入会覆盖原来的内容   
                fileOutputStream = new FileOutputStream(filePath);
                //fileOutputStream = new FileOutputStream(filePath,true);//是追加写入的方式
                //写入一个字节
                //fileOutputStream.write('H');
                //写入一个字符串
                String str = "hello,world";
                //fileOutputStream.write(str.getBytes());//把字符串转成字节数组
                fileOutputStream.write(str.getBytes(), 0, 3);//截取写入
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    fileOutputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    
  4. 文件拷贝

    public class FileCopy {
        public static void main(String[] args) {
            String srcFilePath = "d:\\hello.txt";
            String destFilePath = "d:\\a.txt";
            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.write(buf,0,readLen);//一定要用这个方法
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    if (fileInputStream != null){
                        fileInputStream.close();
                    }
                    if (fileOutputStream != null){
                        fileOutputStream.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    

字符流

  1. FileReadear

    public class FileReader_ {
        /**
         * 单个字符读取
         */
        @Test
        public void readFile1(){
            String filePath = "d:\\story.txt";
            FileReader fileReader = null;
            int data = 0;
            try {
                fileReader = new FileReader(filePath);
                //循环读取
                while ((data = fileReader.read()) != -1){
                    System.out.print((char)data);
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if(fileReader != null){
                    try {
                        fileReader.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    
        /**
         * 字符数组读取
         */
        @Test
        public void readFile2(){
            String filePath = "d:\\story.txt";
            FileReader fileReader = null;
            int readLen = 0;
            char[] buf = new char[8];
            try {
                fileReader = new FileReader(filePath);
                //循环读取
                while ((readLen = fileReader.read(buf)) != -1){
                    System.out.print(new String(buf,0,readLen));
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if(fileReader != null){
                    try {
                        fileReader.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
    
  2. FileWriter

    public class FileWriter_ {
    
        @Test
        public void writeFile() {
            String filePath = "d:\\note.txt";
            FileWriter fileWriter = null;
            char[] c = {'a', 'b', 'c'};
    
            try {
                fileWriter = new FileWriter(filePath);//覆盖模式,后面加true 追加模式
                //写入单个字符
                fileWriter.write('H');
                //写入指定数组
                fileWriter.write(c);
                //写入指定数组的指定部分
                fileWriter.write("LebronJames".toCharArray(), 0, 3);
                //写入整个字符串
                fileWriter.write("Hello,world");
                //写入字符串指定部分
                fileWriter.write("hello", 0, 3);
    
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                //对于FileWriter,一定要关闭流,或者flush,才能将数据真正写入到文件
                try {
                    fileWriter.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    

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

节点流和处理流

  1. 节点流和处理流:
    (1)节点流:节点流可以从一个特定的数据源读写数据,如 FileReader、FileWriter
    (2)处理流:是连接在已存在的流(节点流或处理流)之上,为程序提供更为强大的读写功能,如 BufferedReader、BufferedWriter

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

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

  4. BufferedReader、BufferedWriter均属于字符流,不要去操作二进制文件,可能造成文件损坏,关闭时,只需关闭外层流即可

  5. BufferedReader

    public class BufferedReader_ {
        public static void main(String[] args) throws Exception {
            String filePath = "d:\\a.java";
            BufferedReader bufferedReader = new BufferedReader(new FileReader(filePath));
            //读取
            String line;//按行读取
            while ((line = bufferedReader.readLine()) != null){
                System.out.println(line);
            }
            //关闭流,只需关闭BufferedReader,因为底层会自动关闭节点流
            bufferedReader.close();
        }
    }
    
  6. BufferedWriter

    public class BufferedWriter_ {
        public static void main(String[] args) throws IOException {
            String filePath = "d:\\b.txt";
            BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(filePath));
            //BufferedWriter不能追加,如果要追加,在节点流FileWriter加true,
            //即new BufferedWriter(new FileWriter(filePath,true));
            bufferedWriter.write("hello");
            //在写入多个数据时建议插入一个换行
            bufferedWriter.newLine();//插入换行
            //关闭
            bufferedWriter.close();
        }
    }
    
  7. Buffered拷贝

    public class BufferedCopy_ {
        public static void main(String[] args) {
            String srcFilePath = "d:\\a.java";
            String destFilePath = "d:\\a2.java";
            BufferedReader br = null;
            BufferedWriter bw = null;
            String line;
            try {
                br = new BufferedReader(new FileReader(srcFilePath));
                bw = new BufferedWriter(new FileWriter(destFilePath));
    
                //读取写入
                while ((line = br.readLine()) != null) {
                    bw.write(line);
                    bw.newLine();
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    if (br != null) {
                        br.close();
                    }
                    if (bw != null) {
                        bw.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    
  8. BufferedInputStream、BufferedOutputStream是字节处理流,操作二进制文件,也可以操作文本文件

  9. 使用BufferedInputStream、BufferedOutputStream拷贝和InputStream、OutputStream方式一样

序列化和反序列化

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

  2. 对象处理流 ObjectInputStream、ObjectOutputStream 提供了对基本类型或对象类型的序列化和反序列化的方法,ObjectInputStream 提供反序列化功能,ObjectOutputStream 提供序列化功能

  3. ObjectOutputStream

    public class ObjectOutputStream_ {
        public static void main(String[] args) throws Exception {
            String filePath = "d:\\data.dat";
            ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(filePath));
            //序列化数据到文件
            oos.write(100);//int -> Integer(实现了Serializable)
            oos.writeBoolean(true);//boolean -> Boolean(实现了Serializable)
            oos.writeChar('t');//char -> Character(实现了Serializable)
            oos.writeUTF("tom");//String(实现了Serializable)
            
            oos.writeObject(new Dog("jack" ,10));
            
            oos.close();
        }
    }
    
    class Dog implements Serializable {
        private String name;
        private int age;
    
        public Dog(String name, int age) {
            this.name = name;
            this.age = age;
        }
    }
    
  4. ObjectInputStream

    public class OutInputStream_ {
        public static void main(String[] args) throws Exception {
            String filePath = "d:\\data.dat";
            ObjectInputStream ois = new ObjectInputStream(new FileInputStream(filePath));
    
            //读取
            //读取反序列化的顺序需要和保存数据(序列化)的顺序一致,否则会抛异常
            ois.readInt();
            ois.readBoolean();
            ois.readChar();
            ois.readUTF();
            Object o = ois.readObject();
            System.out.println(o.getClass());
            
            //如果希望调用Dog方法,需要进行向下转型,需要将Dog类的定义拷贝到可以引用的位置
            //此例在同一包内,不需引用
            Dog dog = (Dog)o;
            dog.getName();
            
            //关闭流
            ois.close();
        }
    }
    
  5. 对象处理流注意事项:
    (1)读写顺序要一致
    (2)要求实现序列化和反序列化对象,需要实现 Serializable
    (3)序列化的类中建议添加 SerialVersionUID(序列化版本号,private static final long serialVersionUID = 1L),为了提高版本的兼容性
    (4)序列化对象时,默认将里面所有属性都进行序列化,但除了 static 或 transient 修饰的成员
    (5)序列化对象时,要求里面属性的类型也需要实现序列化接口
    (6)序列化具备可继承性,即如果某类已经实现了序列化,则它的所有子类也已经默认实现了序列化

标准输入流输出流

  1. 标准输入输出流

    \类型默认设备
    System.in 标准输入InputStream键盘
    System.out 标准输出PrintStream显示器
  2. System.in 编译类型是 InputStream,运行类型是 BufferedInputStream

  3. System.out 编译类型和运行类型都是 PrintStream

转换流

  1. 转换流 InputStreamReader 和 OutputStreamWriter,将字节流转换为字符流

  2. InputStreamReade、和OutputStreamWriter基本介绍:
    (1)InputStreamReader:Reader的子类,可以将 InputStream (字节流)包装成 Reader(字符流)
    (2)OutputStreamWriter:Writer的子类,实现将 OutputStream (字节流)包装成 Writer(字符流)
    (3)当处理纯文本数据时,如果使用字符流效率更高,并且可以有效解决中文问题,所有建议将字节流转换成字符流
    (4)可以在使用时指定编码格式,入UTF-8,GBK等

  3. InputStreamReader

    public class InputStreamReader_ {
        public static void main(String[] args) throws Exception {
            String filePath = "d:\\a.txt";
            InputStreamReader isr = new InputStreamReader(new FileInputStream(filePath), "gbk");
            BufferedReader br = new BufferedReader(isr);//读取
            String  s = br.readLine();
            System.out.println(s);
            br.close();
        }
    
  4. OutputStreamReader

    public class OutputStreamWriter_ {
        public static void main(String[] args) throws Exception {
            String filePath = "d:\\b.txt";
            OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(filePath),"gbk");
            osw.write("hi");
            osw.close();
        }
    }
    

打印流

  1. 打印流(只有输出流,没有输入流)分为 PrintStream 和 PrintWriter

  2. PrintStream

    public class PrintStream_ {
        public static void main(String[] args) throws IOException {
            PrintStream out  = System.out;
            out.print("hello");
            //print底层调用的是write方法,所以也可以用write方法
            out.write("hello".getBytes());
            out.close();
            //可以修改打印输出的位置
            System.setOut(new PrintStream("d:\\c.txt"));//修改成打印到这个文件
        }
    }
    
  3. PrintWriter

    public class PrintWriter_ {
        public static void main(String[] args) throws IOException {
            PrintWriter printWriter = new PrintWriter(System.out);
            printWriter.print("hello");
            printWriter.close();
    
            PrintWriter printWriter1 = new PrintWriter(new FileWriter("d:\\d.txt"));
            printWriter1.print("hello~");
            printWriter1.close();
        }
    }
    

Properties

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

  2. Properties类常用方法

    public class PropertiesMethod1 {
        public static void main(String[] args) throws IOException {
            //读取 src 目录下 xxx.properties文件
            Properties properties = new Properties();
            //1. 加载文件 load
            properties.load(new FileReader("src\\xxx.properties"));
            //2. 显示 k-v  list方法
            properties.list(System.out);
            //3. 根据key获取对应的值
            String user = properties.getProperty("user");
            System.out.println(user);
        }
    }
    
    
    public class PropertiesMethod2 {
        public static void main(String[] args) throws IOException {
            //使用Properties类创建或修改文件
            Properties properties = new Properties();
            //创建文件
            //如果该文件没有key,就是创建
            //如果该文件有key,就相当于是修改
            properties.setProperty("charset","utf8");
            properties.setProperty("user","tom");
            properties.setProperty("pwd","abc111");
            //4. 将k-v存储到文件中即可 store方法   null表示不设置注释
            properties.store(new FileOutputStream("src\\mysql2.properties"),null);
        }
    }
    
举报

相关推荐

java学习笔记-IO流

Java:IO流学习笔记二

Java IO流详细学习笔记

# Java基础——IO流

Java基础_IO流

JAVA基础IO流

0 条评论