简述IO流

注:本文章由本人整理笔记。参考韩顺平IO流专题链接在此

目录

1、文件

2、获取文件信息

3、目录操作

4、IO流原理和分类

5、字符输入流

6、 字符输出流

案例:复制粘贴文件

7、FileWriter 和 FileReader

8、节点流和处理流

8.1、BufferedWriter

8.2、BufferedReader

8.3、Buffered拷贝

(1). read()

 (2). readLine()

(3). 复制图片(或复制字节)

9、对象处理流

9.1、序列化

9.2、反序列化



 IO流,就是Input流 (输入流) 和Output流 (输出流) 的简写。Java
 IO流根据处理数据类型的不同分为字符流和字节流,根据数据流向不同分为输入流和输出流,对输入流只能进行读操作,对输出流只能进行写操作,程序中需要根据待传输数据的不同特性而使用不同的流。

1、文件

 文件 :文件,对我们并不陌生,文件是保存数据的地方,比如大家经常使用的word文档,txt文件,excel文件..都是文件。它既可以保存一张图片也可以保持视频,声音...

 创建文件:

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

  1. new File(String pathname) //根据路径构建一个File对象

  2. new File(File parent,String child) //根据父目录文件+子路径构建

  3. new File(String parent,String child) //根据父目录+子路径构建

createNewFile创建新文件

package IO.Demo;

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

public class MakeFile {
    public static void main(String[] args) {
        //创建文档。  方式一:  new File(String pathname);
        // createNewFile();

        File file = new File("f:\\first.txt");
        try {//IO异常
            file.createNewFile();   //返回一个boolean值
            System.out.println("创建成功");
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("创建失败");
        }

        method2();
        method3();
    }

    // 方法二 : new File(File parent,String child) //根据父目录文件 + 子路径构建
    // f:\\second.txt
    public static void method2() {
        File file = new File("f:\\");
        File file1 = new File(file, "second.txt"); 
        //一个file对象 只是一个对象
        // 只有执行了  createNewFile 方法后 才会真正的 在磁盘中 创建这个文件
    //也可以以直接  File file = new File("f:\\second.txt"); 
        try {
            file1.createNewFile();
            System.out.println("创建成功");
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("创建失败");
        }
    }

    方式三 : new File(String parent , String child) //根据父目录+子路径构建
    public static void method3() {
        String parentpath = "f:\\";
        String fileName = "third.doc";
        File file = new File(parentpath, fileName);
        try {
            file.createNewFile();
            System.out.println("创建成功");
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("创建失败");
        }

    }
}

2、获取文件信息

    //先创建文件
        File file = new File("f:\\test.txt");
        try {
            file.createNewFile();
        } catch (IOException e) {
            e.printStackTrace();
        }

        //调用对应方法,得到对应信息
        //getName、getAbsoLutePath、 getParent、 Length、 exists、 isFile、 isDirectory
        System.out.println("文件的名字是:"+file.getName());
        System.out.println("文件的绝对路径是:"+file.getAbsolutePath());
        System.out.println("文件的父级路径是:"+file.getParent());
        System.out.println("文件的大小(字节)是:"+file.length());
        //exists() 返回Boolean值  文件是否存在 
        System.out.println("文件是否存在:"+file.exists());
        System.out.println("是不是一个文件:"+file.isFile());
        System.out.println("是不是一个目录:"+file.isDirectory());
        System.out.println("是不是一个目录:"+file.isAbsolute()); //如果此抽象路径名是绝对的,则该方法返回true,否则该方法返回false。

3、目录操作

 //mkdir 创建一级目录
 //mkdirs 创建多级目录
File file = new File("f:\\demo\\a\\b\\c");
file.mkdirs(); //创建目录
file.delete();  //删除

4、IO流原理和分类

Java IO流原理

  1. IO是 Input/Output 的缩写, I/O技术是非常实用的技术, 用于处理数据传输。

如读/写文件,网络通讯等。

  1. Java程序中, 对于数据的输入/输出操作以”流(stream)"的方式进行。

  2. java.io包 下提供了各种 "流"类和接口, 用以获取不同种类的数据,并通过方 法输入或输出数据

下面四个都是抽象类
        1) Java的I0流共涉及40多个类,实际上非常规则,都是从如上4个抽象基类派生的。
        2)由这四个类派生出来的子类名称都是以其父类名作为子类名后缀。
              InputStream          //字节输入流
              OutputStream          //字节输出流

             Writer                        //字符输出流
              Reader                       //字符输入流

5、字符输入流

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

* FilelnputStream应用实例FileInputStream .java
* 要求:请使用FileInputStream读取hello.txt文件,并将文件内容显示到控制台.

* 单个字节的读取, 效率比较低

        String path = "f:\\hello.txt";
        int readData = 0;  //用于存放读取文件的内容
        FileInputStream fileInputStream = null;

        try {
            //创建对象 用于读取文件
            fileInputStream = new FileInputStream(path);
            //从该输入流读取一个字节的数据。 如果没有输入可用,此方法将阻止
            //如何返回-1 ,表示读取完毕
            while ((readData = fileInputStream.read()) != -1) {
                System.out.print((char) readData);
                 //  读取出来的是ASCLL码。强制转换为 char 类型 
            }

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

   int readData = 0;  //用于存放读取文件的内容

FileInputStream fileInputStream = new FileInputStream(path);
     //读取单个字节, 存放到readData中
readData = fileInputStream.read()
            

6、 字符输出流

使用FileoutputStream 将数据写入文件,如果文件不存在 就 自动创建文件

语法大同小异

 //注:
    //  new FileOutputStream(path); 是 覆盖方式
    //  new FileOutputStream(path,true); 是 追加方式

      String path = "f:\\testOut.txt";
        FileOutputStream fileOutputStream = null;
        try {
            //创建对象
            fileOutputStream = new FileOutputStream(path,true); //追加写入
            //写入一个字节
            fileOutputStream.write('a');

            //写入一个字符串  str.getBytes() 可以把一个字符串 转换成 字节数组
            String str = "我是xxx";
            fileOutputStream.write(str.getBytes());
            System.out.println("写入成功");

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                fileOutputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
      String path = "f:\\testOut.txt";
        FileOutputStream fileOutputStream = null;
        try {
            //创建对象
            fileOutputStream = new FileOutputStream(path,true); //追加写入
            //写入一个字节
            fileOutputStream.write('a');

            //写入一个字符串  str.getBytes() 可以把一个字符串 转换成 字节数组
            String str = "我是麻辣香锅";
            fileOutputStream.write(str.getBytes());
            System.out.println("写入成功");

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                fileOutputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

案例:复制粘贴文件

把 f盘的 拉克丝 文件 拷贝 到 f盘的拉克丝 文件夹中 。因为图片是二进制文件,所以我们用字节流。InputStream和OutputStream

        String path = "f:\\拉克丝.png";
        FileInputStream inputStream = null;
        FileOutputStream outputStream = null;
        String path2 = "f:\\拉克丝\\拉克丝.png";
        File file2 = new File(path2);
        int readData = 0;

        try {
            inputStream = new FileInputStream(path);  //输入流   把文件从F盘 输入到  java程序
            //这里采用覆盖方式输出,
            //如果用追加方式,不会生成多个文件,而会增加文件内存大小
            //输出流, 把文件 输出到 目标地址
            outputStream = new FileOutputStream(path2); 

            while ((readData = inputStream.read()) != -1) {
                outputStream.write(readData);  //将读取到的 文件 写入 新的地址
            }
            if (file2.exists()) {   //如果新的地址存在 (成功写入)
                System.out.println("COPY成功");

            } else {
                System.out.println("copy失败");
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                //关闭流
                inputStream.close();
                outputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }

        }

可见,F盘里的拉克丝图片,已经复制到F盘的 拉克丝文件夹下。

 

7、FileWriter 和 FileReader

FileWriter 和 FileReader是 字符流Writer 和 Reader 的子类

FileWriter可以写入中文

   String path = "f:\\hello.txt";
        FileWriter fileWriter = null;
        String arr = "风雨之后,定见彩虹";  //写入字符串

        char[] x = {'1', '2', '3'};
        try {
            fileWriter = new FileWriter(path, true);
            //4) write (string) :写入整个字符串
            fileWriter.write(arr);

            //1) write(int):写入单个字符
            fileWriter.write('H'); //写入单个字符

            //2) write(char[]):写入指定数组
            fileWriter.write(x);

            //3) write(char[], off,Len):写入指定数组的指定部分
            //从0 开始 写两个
            fileWriter.write(x, 0, 2);

            //5) write (string, off,Len):写入字符串的指定部分
            fileWriter.write(arr, 0, 4);
            System.out.println("写入成功");

            //数据量大的情况下,可以使用循环
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                fileWriter.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

 结果

FileReader可以读取中文         

  String path = "f:\\hello.txt";
        FileReader fileReader = null;
        int FileData = 0 ; //用于存放 文件内容
        //创建FileReader 对象
        try {
            try {
                fileReader = new FileReader(path);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
            while ((FileData = fileReader.read()) != -1){
                System.out.print((char) FileData);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

结果:

8、节点流和处理流

 用BufferedWriter/BufferedReader 可以有Writer / Reader 的 功能。 还可以拓展功能。

8.1、BufferedWriter

import java.io.*;


public class BufferedWriter_ {
    public static void main(String[] args) throws IOException {
        String path = "f:\\hello.txt";
        //创建对象
        BufferedWriter bf = new BufferedWriter(new FileWriter(path));
        //追加写入
        // BufferedWriter bf = new BufferedWriter(new FileWriter(path,true));
        bf.write("你好1.我是熊大!");
        //插入一个和系统相关的换行符
        bf.newLine();
        bf.write("你好2.我是熊二!");
        bf.newLine();
        bf.write("你好3.我是光头强!");
        System.out.println("写入成功!");

        //关闭外层流即可,传入的new FileWriter(path) , 会在底层关闭
        bf.close();
    }
}

 

8.2、BufferedReader


import java.io.*;

public class BufferedReader_ {
    public static void main(String[] args) throws IOException 
    {
        String path = "f:\\hello.txt";
        //创建BufferedReader 对象
        // 用BufferedReader来包装一个 FileReader 对象
        BufferedReader bf = new BufferedReader(new FileReader(path));
        // 按行  读取
        String line; //按行读取 效率高
        /**
         *  说明
         *   bf.readLine();  是按行读取文件
         *   当返回null时 表示文件读取完成
         */

        //可以按行读取
        while ((line = bf.readLine()) != null) {
            System.out.println(line);
        }
        bf.close();
    }
}

8.3、Buffered拷贝

复制字符

(1). read()

public static void main(String[] args) throws IOException {
        //实现字符的复制(字符流)
        String path1 = "f:\\hello.txt";
        String path2 = "f:\\拉克丝\\copy.txt";
        BufferedReader bfr = new BufferedReader(new FileReader(path1));
        BufferedWriter bfw = new BufferedWriter(new FileWriter(path2));
        int readData = 0 ; //用于存放读取的数据

        while ((readData = bfr.read()) != -1 ){
            bfw.write(readData);
        }
        System.out.println("复制成功");
        bfr.close();
        bfw.close();
    }

 (2). readLine()

  //不抛出异常的  要用try catch 来包围
    public static void main(String[] args) {

        //实现字符的复制(字符流)
        String path1 = "f:\\hello.txt";
        String path2 = "f:\\拉克丝\\copy.txt";
        BufferedReader bfr = null;
        BufferedWriter bfw = null;
        String readLine = ""; //用于存放读取 一行 的 数据

        try {
            bfr = new BufferedReader(new FileReader(path1));
            bfw = new BufferedWriter(new FileWriter(path2));
            while ((readLine = bfr.readLine()) != null) {
                bfw.write(readLine);
                bfw.newLine(); //换行两次
                bfw.newLine();
            }
        } catch (IOException e) {
            System.out.println(e);
        } finally {
            try {
                //关闭流
                if (bfr != null) {
                    bfr.close();
                }
                if (bfw != null) {
                    bfw.close();
                }
            } catch (IOException e) {
                System.out.println(e);
            }
        }
    }

(3). 复制图片(或复制字节)

   /**
         * 利用Buffered
         * 将F盘中的 拉克丝.png 复制到 F盘中拉克丝文件夹中(字节流)
         */
        String path1 = "f:\\拉克丝.png";
        String path2 = "f:\\拉克丝\\拉克丝.png";
        //用于存放读取的数据
        int readData = 0;

        //将 拉克丝图片  以二进制流(字节流) 读取过来
        BufferedInputStream bfinput = new BufferedInputStream(new FileInputStream(path1));
        BufferedOutputStream bfoutput = new BufferedOutputStream(new FileOutputStream(path2));
        while ((readData = bfinput.read()) != -1) {
            //写入
            bfoutput.write(readData);
        }

        System.out.println("复制成功");
        //关闭流
        bfinput.close();
        bfoutput.close();
    }

9、对象处理流

➢序列化和反序列化

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

9.1、序列化

public class ObjectInputStream_ {
    public static void main(String[] args) throws Exception {
        String path = "f:\\object.obj";
        //创建流对象
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(path));
        //读取,注意顺序
        //读取的顺序必须要和写入的顺序一致
        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 dog = ois.readObject();
        System.out.println("运行的类型"+dog.getClass());
        System.out.println("狗的信息"+dog);
        ois.close();
    }
}
//如果需要序列化某个对象,要实现Serializable 接口
class Dog implements Serializable {
    private String name;
    private int age;

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

 这样会出现乱码

9.2、反序列化

public class ObjectOutputStream_ {
    public static void main(String[] args) throws IOException {
        //序列化后,保存的文件格式,不是存文本,而是按照他的格式来保存
     //   String path = "f:\\object.obj";
        String path = "f:\\object.obj";
        ObjectOutputStream oos = new  ObjectOutputStream(new FileOutputStream(path));

        //序列化数据 到 path
        oos.writeInt(100);  //int -> Integer  实现了Serializable
        oos.writeBoolean(true);   //boolean  -> Boolean  实现了Serializable
        oos.writeChar('a');  // char ->  character  实现了Serializable
        oos.writeDouble(7.9);  // double ->  Double  实现了Serializable

        oos.writeUTF("我是lmh");  //String  实现了Serializable

        //保存一个dog对象
        oos.writeObject(new Dog("旺财",20));

        //关闭流
        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;
    }
    @Override
    public String toString() {
        return "Dog{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

 结果:

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值