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("src\users.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 写到某一个文件

posted @ 2021-01-21 14:26  keepsummer  阅读(73)  评论(0编辑  收藏  举报