• javaSE-基础-IO流


    一、IO流原理及流的分类

    IO的原理

    IO是Input/Output 的缩写,I/O技术是非常实用的技术,用于处理设备之间的数据传输。如读/写文件,网络通讯等。

    Input (流入) Output (流出)

    按照方向分类 (站在程序这一端)

    输入流(读) :外界数据(磁盘、数据库、网络、键盘(Scanner)) ---> 程序

    输出流(写) :程序--->外界(磁盘、数据库、网络、显示器)

    按照处理数据单位

    字节流 (图片、视频、音频、小文本) :每次操作一个字节

    字符流 (大文本) :每次操作一个字符

    按照角色

    节点流(原始流)就是基础流

    处理流:在节点流的基础上,通过对数据的处理为程序提供更为强大的读写功能。

    image-20210120143650984

    二、流的体系结构

    字节输入流

    InputStream

    BufferedInputStream

    ObjectInputStream

    字节输出流

    OutputStream

    BufferedOutputStream

    ObjectOutputStream

    字符输入流

    Reader

    BufferedReader

    字符输出流

    Writer

    BufferedWriter

    四、四个基础流

    1、 InputStream

     图片只能使用字节流

    a. InputStream 是一个抽象类

    ​ 实现类:FileInputStream 主要是读取磁盘上的文件

    b. FileInputStream的构造器

    ​ FileInputStream(File file);//通过File类对象去构建输入流对象

    ​ FileInputStream(String path);//通过路径去构建处输入流对象

    c. 操作步骤

    ​ a. 创建流对象

    ​ b. 进行读写操作

    ​ c. 关闭资源

    @Test
    public void test1() {
    
    	InputStream input = null;
    	File file =new File("src//python.txt");
    	try {
    		input=new FileInputStream(file);
    		//读写操作
    		int k=-1;
            while((k=input.read())!=-1) {
                System.out.print((char)k);
            }
    	} catch (Exception e) {
        	// TODO Auto-generated catch block
    
       		 e.printStackTrace();
    
        }finally {
            try {
            input.close();
            } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            }
    
        }
    }
    

    d. 读取的方法

    ​ int read();每执行一次读取一个字节,并且指针后移

    length=in.read(b);//将数据存储在byte[]中,返回的int值是读取的字节数int

    ​ int len=in.read(b, 2, 5);//将数据存储在数据中,从指定下标位置(2)开始存,存指定字节数(5)个

    e. 全部读取方式

    ​ ① read() 这个循环之前不能出现read方法

    for (int j2 = 0; j2 < file.length(); j2++) {
    
    	System.out.print((char)in.read());
    
    }
    

    ​ ★ ② b. read() 在读取到没有时返回-1

    //in.read();返回的是读取一次的字节

    int k=0;
    
    while((k=in.read())!=-1){
    
    	System.out.print((char)k);
    
    }
    
    

    ③ in.read(b);

    byte[] b=new byte[(int)file.length()];
    
    int length=in.read(b);
    
    for (int i = 0; i < b.length; i++) {
    
    System.out.print((char)b[i]);
    
    }
    

    ★ ④ in.read(b);

    //input.read(v)返回的是读取了多少个字节(字节数)
    
    byte[] b=new byte[10];
    
    int len;
    
    while((len=in.read(b))!=-1){
    
    for (int i = 0; i < len; i++) {
    
        System.out.print((char)b[i]);
    
    }
    
    }
    

    结论

    • 对于文本文件(.txt ,.java,.c,.cpp),使用字符流处理
    • 对于非文本文件(.JPG,.mp3, .mp4,.avi,.doc,.ppt, .....) 使用字节流处理
    • 使用字节流处理文本文件是可能出现乱码的

    f. 练习

    从磁盘上找一个文件,封装成File对象,作为参数传递给io流,分别采用四种方式读取文件内容到控制台

    @Test
    
    public void test2() {
    
        InputStream input = null;
    
        File file =new File("src//python.txt");
    
        try {
    
            input=new FileInputStream(file);
    
            //读写操作
    
            byte[] b=new byte[10];
    
            int k;
    
            while((k=input.read(b))!=-1) {
    
                for (int i = 0; i < k; i++) {
    
                    System.out.print((char)b[i]);
    
                }
    
    
    
        }
    
        } catch (Exception e) {
    
        // TODO Auto-generated catch block
    
            e.printStackTrace();
    
        }finally {
    
            try {
    
            	input.close();
    
            } catch (IOException e) {
    
            // TODO Auto-generated catch block
    
           	 	e.printStackTrace();
    
            }
    
        }
    
     
    
    }
    

    2、 OutputStream

    a.OutputStream 是一个抽象类

    b.FileOutputStream 一个实现类

    构造器

    FileOutputStream(File file);//写入的内容会覆盖原本的内容

    FileOutputStream(File file,boolean append);//布尔值设置为true,代表追加内容

    FileOutputStream(String path);//写入的内容会覆盖原本的内容

    FileOutputStream(String path,boolean append);//布尔值设置为true,代表追加内容

    c. 特点:

    a. 输出流指向的文件夹必须存在,但是指向的文件是可以不存在的,在新建流时会创建该文件

    d. 常用方法

    write(int b);每次写入一个字节 (和InputStream中read())

    write(b);//将byte[]中的数据全部写入 (和InputStream中的read(b))

    write(b, 2, 3);//奖byte[]中的数据从指定索引值(2)开始写,写入指定个数(3)

    (和InputStream中的read(b,index,length))

    (一般情况下我们都会将此方法和read(b)一起用)

    e. 练习

    1. 将main方法的方法签名写入到d:hello.java

    @Test
    
    public void test1() {
    
        OutputStream out=null;
    
        try {
    
            String str="public static void main(String[] agrs)";
    
            byte [] b=str.getBytes();
    
            out=new FileOutputStream(new File("src//java.java"));
    
    
    
        for (int i = 0; i < b.length; i++) {
    
            out.write(b[i]);
    
        }
    
    
    
        } catch (Exception e) {
    
            // TODO Auto-generated catch block
    
            e.printStackTrace();
    
        }finally {
    
            try {
    
            out.close();
    
            } catch (IOException e) {
    
            // TODO Auto-generated catch block
    
            e.printStackTrace();
    
            }
    
        }
    
    }
    

    2. 将hello.java复制到f盘根目录 从一个文件读到程序,在将内容写入到一个文件

    write(int b)和read()

    write(b, 2, 3); 和 read(b);

    @Test
    
    public void test2() {
    
        InputStream input = null;
    
        OutputStream out=null;
    
        try {
    
            input=new FileInputStream(new File("src//Demo//29.jpg"));
    
            out=new FileOutputStream(new File("src//32.jpg"));
    
            //读操作
    
            byte[] b=new byte[1024];
    
            int k;
    
            while((k=input.read(b))!=-1) {
    
            for (int i = 0; i < k; i++) {
    
            out.write(b[i]);
    
            }
    
            }
    
    
    
        } catch (Exception e) {
    
        // TODO Auto-generated catch block
    
            e.printStackTrace();
    
        }finally {
    
            try {
    
            input.close();
    
            out.close();
    
            } catch (IOException e) {
    
            // TODO Auto-generated catch block
    
            e.printStackTrace();
    
            }
        }
    }
    

    3 、Reader

    a. Reader 也是一个抽象类

    b. 实现类 FileReader (操作方式和InputStream类似,只是操作的单位不一样)

    构造器

    FileReader(File file)

    FileReader(String path)

    c. 常用方法

    read();每次读取一个字符

    read(char[] c);将读取的内容存放在char[]中,返回的是读取的字符数

    len=r.read(c, 3, 5);将读取的数据内容存放在char[]中,从指定索引值(3)开始存,存指定个数(5)的字符

    d. 读取全部内容的方式

    a. read();

    int i;

    while((i=r.read())!=-1){

    System.out.print((char)i);

    }

    b. read(c);

    char[] c=new char[5];

    int len=0;

    while((len=r.read(c))!=-1){

    for (int i = 0; i < len; i++) {

    System.out.print(c[i]);

    }

    }

    4、 Writer

    ① Writer是一个抽象类

    ② 实现类是 FileWriter

    • 输出操作对应的file 可以不存在,

      • 如果不存在,输出的过程中会自动创建此文件。

      • 如果存在fileWriter(file,false)/fileWriter(file)自动覆盖,fileWriter(file,ture 追加

    构造器

    ​ FileWriter(File file) //覆盖内容

    ​ FileWriter(File file, boolean append) //追加内容

    ​ FileWriter(String path)

    ​ FileWriter(String path, boolean append)

    ③ 常用方法

    ​ write(int b);每次写一个字符

    ​ write(char[] c);将char[]中的数据全部写入

    ​ write(char[] c,int off,int length);将数组中的数据 从off开始写,写length个

    ​ write(String str);将字符串内容全部写入

    ​ write(String str,int off,int length);将字符串中的 字符从off开始写,写length个

    ④. 练习

    使用字符流完成文件的复制,两种方式去实现

    @Test
    
    public void test1() {
    
    	Reader r=null;
    
    	Writer w=null;
    
    	try {
    
    		w=new FileWriter(new 					File("src//Demo//copy.txt"));
    
    		r=new FileReader(new 			File("src//python.txt"));
    
    		int len;
    
    		char[] c=new char[5];
    
    		while((len=r.read(c))!=-1) {
    
    			w.write(c,0,len);
    
    		}
    
    	} catch (Exception e) {
    
    	// TODO Auto-generated catch block
    
    	e.printStackTrace();
    
    	}finally {
    
    	try {
    
    	r.close();
    
    	w.close();
    
    	} catch (IOException e) {
    
    	// TODO Auto-generated catch block
    
    	e.printStackTrace();
    
    	}
    	}
    }
    
    @Test
    
    public void test2() {
    
        Reader r=null;
    
        Writer w=null;
    
        try {
    
            w=new FileWriter(new File("src//Demo//copy.txt"));
    
            r=new FileReader(new File("src//python.txt"));
    
            int len;
    
            while((len=r.read())!=-1) {
    
                w.write((char)len);
    
            }
    
        } catch (Exception e) {
    
            // TODO Auto-generated catch block
    
            e.printStackTrace();
    
        }finally {
    
            try {
    
                r.close();
    
                w.close();
    
            } catch (IOException e) {
    
            // TODO Auto-generated catch block
    
                e.printStackTrace();
    
            }
    
    
        }
    
    }
    

    5、缓冲流

    a. 字节流 输入流 缓冲流

    字节输入缓冲流在使用上和InputStream没有差别,只不过自带一个缓冲区,提高效率

    BufferedInputStream in=
    
    new BufferedInputStream(
    
    new FileInputStream(new File("d:\hello.java")));
    

    b. 字节流 输出流 缓冲流

    字节输出缓冲流在使用上和OutputStream没有差别,只不过自带一个缓冲区,提高效率

    BufferedOutputStream out=
    
    new BufferedOutputStream(new FileOutputStream("f:\aa.txt"));
    

    c. 字符流 输入流 缓冲流

    字符输入缓冲流在使用上功能要比Reader多一个readLine();其他方法使用是一致的

     //in.readLine();每次读取一行,读到末尾返回null
    
     BufferedReader in=
    
    new BufferedReader(
    
    new FileReader("f:\hello.java"));
    
    String str=null;
    
    while((str=in.readLine())!=null){
    
    System.out.println(str);
    
    }
    

    d. 字符流 输出流 缓冲流

    字符输出缓冲流在使用上功能比Writer多了一个newLine();其他的使用是一致的

    //newLine();新的一行 一个换行
    
    BufferedWriter out=
    
    new BufferedWriter(
    
    new FileWriter("f:\world.java"));
    
    out.write("今天是周五");
    
    out.newLine();//新的一行 一个换行
    
    out.write("明天是周六");
    
    out.close();
    

    6、对象流

    Java中的对象<———>文件

    a.ObjectInputStream

    1. 创建对象
    ObjectInputStream in=
    
    new ObjectInputStream(
    
    new FileInputStream("f:\person.txt"));
    
    1. readInt();readByte();readObject()...

    注意:写入的方法和读取的方法类型要一致

    b.ObjectOutputStream

    1. 创建对象
    ObjectOutputStream out=
    
    new ObjectOutputStream(
    
    new FileOutputStream("f:\person.txt"));
    

    2. 常用方法

    writeInt();writeByte();writeObject();...

    3. 对象流写入对象时,对 对象有些要求,这个对象必须能序列化

    序列化的步骤 实现Serializable接口,(该接口中没有任何抽象方法)

    并添加:private static final long serialVersionUID = 1L;

    作用:主要是为了版本的兼容性

    3. 练习

    自己创建一个类,然后创建该类的对象,并将该对象写入到一个文件中,在读取出来

    * 此文件主要演示:把对象存储到文本文件中,使用对象输入流和对象输出流

    public void test1() {
    
    ObjectOutputStream obj=null;
    
    ObjectInputStream in=null;
    
    try {
    
    obj=
    
    new ObjectOutputStream(
    
    new FileOutputStream(
    
    new File("src//Demo//animal.text")));
    
    in=
    
    new ObjectInputStream(
    
    new FileInputStream(
    
    new File("src//Demo//animal.text")));
    
    obj.writeObject(new Animal("灯泡",1));
    
     
    
    Object o=in.readObject();
    
    System.out.println(o);
    
     
    
    } catch (Exception e) {
    
    // TODO Auto-generated catch block
    
    e.printStackTrace();
    
     
    
    }finally {
    
    try {
    
    obj.close();
    
    in.close();
    
    } catch (IOException e) {
    
    // TODO Auto-generated catch block
    
    e.printStackTrace();
    
    }
    
    }
    
    }
    
    }
    
    class Animal implements Serializable{
    
     
    
    private static final long serialVersionUID = 7809121654099691241L;
    
     
    
        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;
    
    }
    
    @Override
    
    public String toString() {
    
        return "Animal [name=" + name + ", age=" + age + "]";
    
    }
    
    public Animal(String name, int age) {
    
        super();
    
        this.name = name;
    
        this.age = age;
    
    }
    }
    

    7、打印流

    a.打印流 主要处理的是 输出流

    b. 字节打印输出流 PrintStream

    构造器

    PrintStream(OutputStream out);

    PrintStream(OutputStream out, boolean autoFlush);//带自动刷新功能

    c.字符打印输出流 PrintWriter

    构造器

    PrintWriter(Writer out);

    PrintWriter(Writer out, boolean autoFlush);

    d. 特点

    a. 提供了一系列重载的print和println方法,用于多种数据类型的输出

    b. PrintStream和PrintWriter的输出不会抛出异常

    c. PrintStream和PrintWriter有自动flush功能

    只针对 println, printf,或 format

    d. System.out返回的是PrintStream的实例

    构造器

    printStream(OutputStream out);

    8、标准输入输出流

    标准的输入输出流

    1、printStream=System.out ——————-(显示器:控制台)

    更改System.out的指向位置

    setOut(OutputStream out)

    2、InputStream=System.in-----------------------(键盘)

    更改System.in的指向位置

    System.SetIn(InputStream in);

    PrintStream =System.err();//打印字体是红色的

    9、转换流

    1. 字节流 ---> 字符流

    a. 输入流

    InputStream--->Reader

    Reader r=new InputStreamReader(InputStream,String charset);//String charset。 指定字符集
    

    b. 输出流

    OutputStream--->Writer

     Writer w=new OutputStreamWriter(OutputStream,String charset);
    
    1. 练习

    模仿Scanner制作一个readLine() 读一行

    (System.in、InputStreamReader、BufferedReader)
    
    package homework;
    
    import java.io.BufferedInputStream;
    
    import java.io.BufferedReader;
    
    import java.io.IOException;
    
    import java.io.InputStream;
    
    import java.io.InputStreamReader;
    
    import java.io.Reader;
    
     
    
    /*1.去模仿Scanner去写俩个方法
    
    nextLine();//获取一行  BufferedReader 
    
    nextInt();
    
    */
    
     
    
    public class homework {
    
    public static void main(String[] args) {
    
        // nextLine();
    
        nextInt();
    
    }
    
    public static void nextLine() {
    
        System.out.println("请输入文字:");
    
        InputStream in=System.in;//接收键盘输入
    
        Reader r=new InputStreamReader(in);//使用字节流转换成字符流
    
        BufferedReader br=new BufferedReader(r);//Reader转换成缓冲字符流
    
        String str=null;
    
        try {
    
        str = br.readLine();
    
        } catch (IOException e) {
    
        // TODO Auto-generated catch block
    
        e.printStackTrace();
    
        }
    
        System.out.println(str);
    
     
    
    }
    
    public static void nextInt() {
    
        System.out.println("请输入数字:");
    
        InputStream in=System.in;//接收键盘输入
    
        Reader r=new InputStreamReader(in);//使用字节流转换成字符流
    
        BufferedReader br=new BufferedReader(r);//Reader转换成缓冲字符流
    
        String a=null;
    
        try {
    
        while((a = br.readLine())!=null) {
    
        System.out.print(a);
    
        }
    
     
    
        } catch (IOException e) {
    
        // TODO Auto-generated catch block
    
        e.printStackTrace();
    
        }
    }
    }
     
    

    10、Properties

    此类用于演示Map集合实现类 Properties

    1. Properties HashTable的子类 所以具备HashTable所有的特点

    一般读取配置文件

    1. Properties能够读取配置文件(文件名.properties/.xml)

    文件名.properties的编码格式为 ISO-8859-1

    Properties pro=new Properties();

    1. pro.load(new FileInputStream("srcusers.properties"));指向配置文件

    getProperty(String key);根据key值获取value值

    getProperty(String key,String defaultValue);根据key值获取value值,如果取不到返回默认值

    pro.list(System.out);打印文件所有内容

    1. 写入常用方法

    Properties pro=new Properties();

    setProperty(String key, String value);设置文件内容

    pro.store(OutputStream out, String commons);设置写到的位置OutputStreamout 写到某一个文件

  • 相关阅读:
    异常处理基本语法
    数字取舍(trunc round ceil floor)
    关于union的理解
    SQL Loader 导入EXCEL 数据到ORACLE 数据库
    临时表的使用方法
    对外投资
    存货盘盈盘亏核算
    现金流量表补充资料的编制公式
    会计科目的具体定义
    中英文职位对照之 会计与财务
  • 原文地址:https://www.cnblogs.com/minmin123/p/14307810.html
Copyright © 2020-2023  润新知