Java IO流(字节流、字符流、缓冲流、转换流、序列化、打印流)

文章目录

  • IO流(入门)
    • 1 字节流
      • 1.1 字节输出流OutputStream
      • 1.2 文件字节输出流FileOutputStream
      • 1.3 字节输出入流InputStream
      • 1.4 文件字节输出入流FileInputStream
    • 2 字符流
      • 2.1 字符输入流Reader
      • 2.2 文件字符输入流FileReader
      • 2.3 字符输出流Writer
      • 2.4 文件字符输出流FileWriter
        • try/catch更新后用法
      • 2.5 Properties
  • IO流(高阶)
    • 3 缓冲流
      • 3.1 字节缓冲流
        • BufferedInputStream
        • BufferedOutputStream
      • 3.2 字符缓冲流
        • BufferedWriter
        • BufferedReader
    • 4 转换流
      • InputStreamReader
      • OutputStreamWriter
    • 5 对象序列化
      • 5.1 序列化流ObjectOutputStream
      • 5.2 反序列化流ObjectInputStream
        • 反序列化(修改序列号)
      • 5.3 序列化集合
    • 6 打印流
    • 7 Scanner
    • next 和 nextLine

IO流(入门)

用于硬盘和内存之间的数据交互,input内存读取,output内存输出

输入流 输出流
字节输入流InputStream 字节输出流OutputStream
字符输入流Reader 字节输出流Writer

1 字节流

一切文件数据都是以字节的形式保存的。不管什么养的流对象都是在传输字节。

1.1 字节输出流OutputStream

java.io.OutputStream它是所有输出流的抽象父类,子类名称前半部分表示自己的输出类型,后半部分表示父类如:FileOutputStream输出到文件中,ObjectOutputStream输出对象类

方法 描述
void close​() 关闭此输出流并释放与此流相关联的任何系统资源。
void flush​() 刷新此输出流并强制任何缓冲的输出字节被写出。
void write​(byte[] b) 将 b.length字节从指定的字节数组写入此输出流。
void write​(byte[] b, int off, int len) 从指定的字节数组写入 len字节,从偏移量 off开始输出到此输出流。
abstract void write​(int b) 将指定的字节写入此输出流。

1.2 文件字节输出流FileOutputStream

把内存中的数据写入到文件中。打开文件并写入文件,文件不存在则会创建该文件。

向文件中追加/续写内容

构造方法 功能
FileOutputStream(String name,boolean append) 创建一个向制定name文件写入数据的输出流
FileOutputStream(File file,boolean append) 创建一个向指定file对象表示的文件中写入数据的输出流
append 是追加写开关
换行:
windows:\r\n
linux:\n
mac:\r

写入数据时,会把写入的十进制数字,转换为二进制数字写入文件,.txt文件编辑器会查询编码表,把字节流转换为字符流

File f = new File("C:/java/hello");
OutputStream os = new FileOutputStream(f);
os.write(数组);
os.close();

1.3 字节输出入流InputStream

所有字节输入流类的超类

方法 功能
void close​() 关闭此输入流并释放与流相关联的任何系统资源。
abstract int read​() 从输入流读取数据的下一个字节。
int read​(byte[] b) 从输入流中读取一些字节数,并将它们存储到缓冲器阵列 b 。

1.4 文件字节输出入流FileInputStream

构造方法 功能
FileInputStream​(File file) 通过打开与实际文件的连接来创建一个 FileInputStream ,该文件由文件系统中的 File对象 file命名。
FileInputStream​(String name) 通过打开与实际文件的连接来创建一个 FileInputStream ,该文件由文件系统中的路径名 name命名。
File f = new File("C:/java/hello");
FileInputStream fis = new FileInputStream(f);
(char)fis.read()//不可以这么判断,会导致一次值没有接收
int res;
while(fis.read()!=-1)
//正确
while((res = fis.read())!=-1)
	System.out.println((char)res);
fis.close()

int len=0;
byte b = new byte[1024];//通常设为1024或其整数倍
int len = fis.read(b);返回有效字符长度

while((len = fis.read(b))!= -1){
	System.out.println(new String(b),0,len);
}

2 字符流

2.1 字符输入流Reader

方法 功能
abstract void close​() 关闭流并释放与之相关联的任何系统资源。
int read​() 读一个字符
int read​(char[] cbuf) 将字符读入数组。
abstract int read​(char[] cbuf, int off, int len) 将字符读入数组的一部分。

2.2 文件字符输入流FileReader

FileReader继承了InputStreamReader(实现了Reader接口)

构造方法 功能
FileReader​(File file) 创建一个新的 FileReader ,给出 File读取。
FileReader​(String fileName) 创建一个新的 FileReader ,给定要读取的文件的名称。
//单个字符读取文件
FileReader fr = new FileReader("day07maven/c.txt");

int len = 0;
while ((len = fr.read())!=-1){
	System.out.print((char)len);
}
//字符数组读取文件
FileReader fr = new FileReader("day07maven/chai.txt");
char[] c = new char[1024];

int len = 0;
while ((len = fr.read(c))!=-1){
	System.out.print(new String(c,0,len));
}

2.3 字符输出流Writer

所有写字符流的顶层父类,是一个抽象类
Java IO流(字节流、字符流、缓冲流、转换流、序列化、打印流)_第1张图片

2.4 文件字符输出流FileWriter

FileWriter继承了OutputStreamWriter类(该类实现了Writer接口)
Java IO流(字节流、字符流、缓冲流、转换流、序列化、打印流)_第2张图片
字节流会将字节数据直接写入文件,即使没有close输出流,但是FileWriter调用完writer必须调用flush或者close才能把数据从内存缓冲区写入文件。

FileWriter fw = new FileWriter("day07maven/chai.txt",true);
fw.write("\rio种类可真多");
fw.flush();
fw.close();

flush和close区别:

  • flush:刷缓冲区新后 写出流还可以继续使用
  • close:先刷新缓冲区,再关闭流

try/catch更新后用法

try(对象声明){
	可能产生异常代码
}catch{
处理
}
try(
	FileInputStream fis = new FileInputStream("day07maven/chai.txt",true);
){
	int len = 0;
	while((len = fls.read())!= -1){
		System.out.println(len);
	}
}catch(IOException e){
System.out.println(e);
}

2.5 Properties

java.util.Properties集合 extends Hashtable implement Map
Properties类表示了一个持久的属性集,可以保存在流中,或从流中加载。他是唯一和IO流相结合的集合,今后常用于 配置文件

方法 功能
void load​(InputStream inStream) 从输入字节流读取属性列表(键和元素对)。
void load​(Reader reader) 以简单的线性格式从输入字符流读取属性列表(关键字和元素对)。
void store​(OutputStream out, String comments) 将此 Properties表中的此属性列表(键和元素对)以适合于使用 load(InputStream)方法加载到 Properties表格的格式写入输出流。
void store​(Writer writer, String comments) 将此属性列表(键和元素对)写入此 Properties表中,以适合使用 load(Reader)方法的格式输出到输出字符流。
Object setProperty​(String key, String value) 调用 Hashtable方法 put 。
String getProperty​(String key) 使用此属性列表中指定的键搜索属性。
Set stringPropertyNames​() 从该属性列表中返回一个不可修改的键集,其中键及其对应的值是字符串,包括默认属性列表中的不同键,如果尚未从主属性列表中找到相同名称的键。
public static void main(String[] args) {
    try(
        FileWriter fw = new FileWriter("day07maven/test.properties");
        FileReader fr = new FileReader("day07maven/test.properties");
    ){
        //创建Properties集合并传入数据
        Properties pro = new Properties();
        pro.setProperty("name","c");
        pro.setProperty("age","22");
        
        //将集合中数据写入.properties文件
        pro.store(fw,"save data");
        
        //加载.properties文件,通过key值
        pro.load(fr);
        String name = pro.getProperty("name");
        int age = Integer.parseInt(pro.getProperty("age"));
        //打印
        System.out.println(name+": "+age);
    }catch(IOException e){
        System.out.println(e);
    }
}

IO流(高阶)

3 缓冲流

缓冲流也称高效流,是对四个基本Filexxx流的增强,所以也分为四个流。原本的流单个字节或字符进行传输,缓冲流增加缓冲区,同时对大量数据进行操作,提高效率。

字节缓冲流 字符缓冲流
BufferedInputStream BufferedReader
BufferedOutputStream BufferedWriter

3.1 字节缓冲流

BufferedInputStream

Java IO流(字节流、字符流、缓冲流、转换流、序列化、打印流)_第3张图片

public static void main(String[] args) {
    try(
            FileInputStream fis = new FileInputStream("day07maven/chai.txt");
            BufferedInputStream bis = new BufferedInputStream(fis);
            ){
        byte[] b = new byte[1024];
        int len = 0;
        while ((len = bis.read(b))!=-1){
            System.out.println(new String(b,0,len));
        bis.close();
        }
    }catch (IOException e){
        e.printStackTrace();
    }
}

BufferedOutputStream

Java IO流(字节流、字符流、缓冲流、转换流、序列化、打印流)_第4张图片

public static void main(String[] args) {
    try(
        FileOutputStream fos = new FileOutputStream("day07maven/chai.txt",true);
        BufferedOutputStream bos = new BufferedOutputStream(fos);
        bos.flush();
    ){
        bos.write(new String("--BufferedOutputStream").getBytes());
    }catch(IOException e){
        e.printStackTrace();
    }
}

3.2 字符缓冲流

BufferedWriter

方法 功能
void newLine​() 写一行行分隔符。
public static void main(String[] args) {
    try (
            FileWriter fw = new FileWriter("day07maven/chai.txt");
            BufferedWriter bw = new BufferedWriter(fw);
    ) {
        bw.write("缓冲字符输出流");
    } catch (IOException e) {
        e.printStackTrace();
    }
}

BufferedReader

方法 功能
String readLine​() 读一行文字。
public static void main(String[] args) {
    try(
            FileReader fr = new FileReader("day07maven/chai.txt");
            BufferedReader br = new BufferedReader(fr);
            ){
        char[] b = new char[1024];
        int len = 0;
        while ((len = fr.read(b))!=-1){
            System.out.println(new String(b,0,len));
        }
    }catch (IOException e){
        e.printStackTrace();
    }
}

4 转换流

FileReader作为InputStreamReader子类,设定了默认编码表进行读取数据,FileWriter类似。InputStreamReaderOutputStreamWriter作为可以设定编码方式的流,被称为转换流

InputStreamReader

InputStreamReader是从字节流到字符流的桥梁:它读取字节,并使用指定的charset将其解码为字符。 它使用的字符集可以由名称指定,也可以被明确指定,或者可以接受平台的默认字符集。Java IO流(字节流、字符流、缓冲流、转换流、序列化、打印流)_第5张图片

OutputStreamWriter

OutputStreamWriter是从字符流到字节流的桥梁:使用指定的charset将写入的字符编码为字节。 它使用的字符集可以由名称指定,也可以被明确指定,或者可以接受平台的默认字符集。
Java IO流(字节流、字符流、缓冲流、转换流、序列化、打印流)_第6张图片


5 对象序列化

把对象以流的方式写如文件保存,即写对象也叫做对象的序列化。
Java IO流(字节流、字符流、缓冲流、转换流、序列化、打印流)_第7张图片

5.1 序列化流ObjectOutputStream

Java IO流(字节流、字符流、缓冲流、转换流、序列化、打印流)_第8张图片

方法 功能
void writeObject​(Object obj) 将指定的对象写入ObjectOutputStream。

5.2 反序列化流ObjectInputStream

Java IO流(字节流、字符流、缓冲流、转换流、序列化、打印流)_第9张图片

方法 功能
Object readObject​() 从ObjectInputStream读取一个对象。
  • 要进行序列化和反序列化的类需要对Serializable接口以启用序列化功能
  • 反序列化必须存在对应的class文件
  • 对象进行序列化时检测是否实现接口
  • 没有实现报出NotSerializableException异常,对象... implements Serializable
  • static关键字声明的变量,提前进入内存,被所有对象共享,不属于任何对象,所以不能序列化
  • tranisent关键字声明的变量不能被序列化,有静态的功能,没有静态的含义

反序列化(修改序列号)

反序列化时,会给对象类生成序列号serialVersionUID,反序列化时如果类出现修改,序列号改变,反序列化会报错
为了解决这个问题,我们可以在类中声明静态不可变的序列号,保证序列号不变

public class Person implements Serializable{
	//设定序列号
	private static finall long serialVersionUID = 1L;
	private String name;
	public Person(){}
}

5.3 序列化集合

当我们在文件中存储多个对象的时候,可以把多个对象存储到一个集合中,对集合序列化和反序列化

public static void main(String[] args) throws IOException, ClassNotFoundException {
    ArrayList<Person> list = new ArrayList<>();
    list.add(new Person("a"));
    list.add(new Person("b"));
    list.add(new Person("c"));

    ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("day07maven/chai.txt"));
    oos.writeObject(list);
    ObjectInputStream ois = new ObjectInputStream(new FileInputStream("day07maven/chai.txt"));
    Object o = ois.readObject();
    ArrayList<Person> olist= (ArrayList<Person>)(o);
    for (Person person : olist) {
        System.out.println(person);
    }
    oos.close();
    ois.close();
}
//内部Person类
static class Person implements Serializable {
    private static final long serialVersionUID = 1L;
    private String name;

    public Person(String name){
        this.name = name;
    }

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

6 打印流

java.io.PrintStream打印流可以打印任何数据表示形式。

  • 只负责数据输出
  • PrintStream 不会抛出IOException
  • 特有方法print println
  • 如果调用父类方法write则查看数据时会查询编码表97->a,使用自己特有方法print 数据原样输出
public static void main(String[] args) throws FileNotFoundException {
    PrintStream ps = new PrintStream("day07maven/printstream.txt");
    ps.println(97);
    ps.println('a');
    ps.println("string");
    ps.println(true);
    ps.println(8.8);
    ps.close();
}
public static void main(String[] args) throws FileNotFoundException {
    System.out.println("在控制台输出");

    PrintStream ps = new PrintStream("day07maven/printstream.txt");

    //将输出语句的目的地修改为打印流目的地
    System.setOut(ps);
    System.out.println("在打印流目的地输出");
    ps.close();
    }

结果:
Java IO流(字节流、字符流、缓冲流、转换流、序列化、打印流)_第10张图片
Java IO流(字节流、字符流、缓冲流、转换流、序列化、打印流)_第11张图片


7 Scanner

  • 通过scanner获取用户输入
  • 通过next() nextLine()获取字符串,使用前通常用hasNext hasNextLine判断是否还有输入

next 和 nextLine

next():

1、一定要读取到有效字符后才可以结束输入。
2、对输入有效字符之前遇到的空白,next() 方法会自动将其去掉。
3、只有输入有效字符后才将其后面输入的空白作为分隔符或者结束符
next() 不能得到带有空格的字符串

nextLine():

1、以Enter为结束符,也就是说 nextLine()方法返回的是输入回车之前的所有字符。
2、可以获得空白。

//scanner接收数据求平均值

public static void main(String[] args) {
    Scanner scan = new Scanner(System.in);

    double sum = 0;
    int m = 0;

    while (scan.hasNextDouble()) {
        double x = scan.nextDouble();
        m = m + 1;
        sum = sum + x;
    }

    System.out.println(m + "个数的和为" + sum);
    System.out.println(m + "个数的平均值是" + (sum / m));
    scan.close();
}
12
23
15
21.4
end // 输入非数字结束输入
4个数的和为71.4
4个数的平均值是17.85

手写不易,点赞感谢

你可能感兴趣的:(Java)