IO流(其他流):数据输入输出流;内存操作流;打印流;序列化与反序列化流;随机访问流;Properties

IO流(其他流)

一、数据输入输出流

1、特有属性

特点:可以读写基本类型数据
数据输入流:
	DataInputStream(InputStream in) //使用指定的底层 InputStream 创建一个 DataInputStream
数据输出流:
    DataOutputStream(OutputStream out)// 创建一个新的数据输出流,将数据写入指定基础输出流   

2、特有方法演示

import java.io.*;

public class MyTest {
    public static void main(String[] args) throws IOException {
        write();
        read();
    }

    private static void read() throws IOException {
        DataInputStream in = new DataInputStream(new FileInputStream("a.txt"));
        //注意:读写数据类型顺序要一致,否则会报错
        boolean b = in.readBoolean();
        byte b1 = in.readByte();
        char c = in.readChar();
        String s = in.readUTF();
        in.close();
    }

    private static void write() throws IOException {
        DataOutputStream out = new DataOutputStream(new FileOutputStream("a.txt"));
        out.writeBoolean(true);
        out.writeByte(99);
        out.writeChar('1');
        out.writeUTF("abc");
        out.close();
    }
}

二、内存操作流

	不关联任何文件,只是在内存中对数据进行操作,此流无需关闭,关闭无效

1、操作字节数组的内存操作流

	ByteArrayOutputStream:此类实现了一个输出流,其中的数据被写入一个 byte 数组。缓冲区会随着数据的不断写入而自动增长。可使用 toByteArray()toString() 获取数据。 
	ByteArrayInputStream :包含一个内部缓冲区,该缓冲区包含从流中读取的字节
演示:
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Arrays;

public class MyTest1 {
    public static void main(String[] args) throws IOException {
        ByteArrayOutputStream baOut = new ByteArrayOutputStream();
        baOut.write("abcd".getBytes());
        baOut.write("1234".getBytes());
        byte[] bytes = baOut.toByteArray();//将缓冲区的数据转为字节数组
        System.out.println(Arrays.toString(bytes));//[97, 98, 99, 100, 49, 50, 51, 52]
        String s = baOut.toString();//将缓冲区的数据转为字符串
        System.out.println(s);//abcd1234

        ByteArrayInputStream baIn = new ByteArrayInputStream(bytes);
        byte[] bytes1 = new byte[1024 * 8];
        int len = baIn.read(bytes1);
        String s1 = new String(bytes1, 0, len);
        System.out.println(s1);//abcd1234
    }
}

2、操作字符数组的内存操作流

//操作字符数组
// CharArrayWrite
//CharArrayReader
import java.io.CharArrayWriter;
import java.io.IOException;

public class MyTest2 {
    public static void main(String[] args)throws IOException {
        CharArrayWriter writer = new CharArrayWriter();
        writer.write("abc");
        writer.write("abc");
        char[] chars = writer.toCharArray();
        String s = writer.toString();
    }
}

3、操作字符串的内存操作流程

//StringWriter:内部使用StringBuffer实现
//StringReader
import java.io.StringWriter;

public class MyTest3 {
    public static void main(String[] args) {
        StringWriter stringWriter = new StringWriter();
        stringWriter.write("abc");
        stringWriter.append("abc");//可以调用StringBuffer的append方法写入数据
        String s = stringWriter.toString();
        System.out.println(s);
    }
}

三、打印流

打印流的特点
	a: 打印流只能操作目的地,不能操作数据源(不能读取数据)
	b: 可以操作任意数据类型的数据 调用print() 方法可以写任意数据类型
	c: 自动刷新:必须调用println、printf 或 format 方法中的一个方法,且通过以下构造创建对象,能够启动自动刷新
  	 public PrintWriter(OutputStream out,  boolean autoFlush)//参2位true启动自动刷新
  	 public PrintWriter(Writer out,  boolean autoFlush)//参2位true启动自动刷新
	d: 这个流可以直接对文件进行操作(构造方法的参数可以传递文件或者文件路径)

1、字符打印流

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;

public class MyTest4 {
    public static void main(String[] args) throws IOException {
        PrintWriter writer = new PrintWriter(new FileOutputStream("c.txt"),true);
        writer.println("abc");
        writer.println(123);
        writer.println(true);
        //writer.flush();以启用自动刷新,可不用再手动刷新
        writer.close();
    }
}

2、字节打印流

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;

public class MyTest5 {
    public static void main(String[] args) throws IOException {
        PrintStream printStream = new PrintStream(new FileOutputStream("b.txt"));
        printStream.write("字节打印流".getBytes());
        printStream.print(true);
        printStream.println(100);
        printStream.close();

        PrintStream out = System.out;
        out.write("abc".getBytes());
        out.println(3.14);//abc3.14
    }
}

3、使用字节打印流和Scanner类复制文本文件

import java.io.FileInputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Scanner;

public class MyTest7 {
    public static void main(String[] args)throws IOException {
        Scanner sc = new Scanner(new FileInputStream("a.txt"));//使用Scanner读取文件
        PrintWriter writer = new PrintWriter("b.txt");
        while (sc.hasNextLine()){
            writer.println(sc.nextLine());//一次读写一行,并换行
            writer.flush();
        }
        sc.close();
        writer.close();
    }
}

四、序列化与反序列化流

序列化:把对象保存到硬盘上
反序列化:把对象读到内存中
序列化流:
ObjectOutputStream 
out.writeObject(对象);//要求对象类实现Serializable(标记接口)
public static final long serialVersionUID=1L;
//如果要存储多个对象,可以将对象存到集合中,再将集合存到硬盘中
//如果某一个成员变量不想被序列化,可以使用关键字transient修饰
反序列化流:
ObjeceInputStream
in.readObject();

演示

import java.io.*;
import java.util.ArrayList;

public class MyTest4 {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        write();

        ObjectInputStream objIn = new ObjectInputStream(new FileInputStream("a.txt"));
        Object object = objIn.readObject();//读取文件,获取集合对象
        ArrayList<Student> list= (ArrayList<Student>) object;
        for (Student student : list) {
            System.out.println(student.getName());
        }
    }

    private static void write() throws IOException {
        Student zhangsan = new Student("zhangsan");
        Student lisi = new Student("lisi");
        Student wangwu = new Student("wangwu");
        ArrayList<Student> list = new ArrayList<>();
        list.add(zhangsan);
        list.add(lisi);
        list.add(wangwu);
        ObjectOutputStream objout = new ObjectOutputStream(new FileOutputStream("a.txt"));
        objout.writeObject(list);//将集合对象写入文件中
    }
}
class Student implements Serializable{//必须实现Serializable接口
    //保证serialVersionUID不变
    public static final long serialVersionUID = -3508803735981209248L;
    private String name;

    public Student() {
    }

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

五、随机访问流

RandomAccessFile特点:能读能写,有文件指针,可以记录文件读写的位置
RandomAccessFile(fileName,"rw“)//参2位可读可写
 	获取文件指针位置:getFilePointer()
    设置指针位置:seek()           

1、演示

import java.io.IOException;
import java.io.RandomAccessFile;

public class MyTest4 {
    public static void main(String[] args)throws IOException {
        RandomAccessFile ra = new RandomAccessFile("e.txt", "rw");
        RandomAccessFile ra2 = new RandomAccessFile("e.txt", "rw");
        ra.writeBoolean(true);
        
        boolean b = ra2.readBoolean();//注意读取与写入数据类型一致,否则报错
        System.out.println(b);
        
        long l = ra2.getFilePointer();//获取文件指针位置
        System.out.println(l);
        ra2.seek(0);//设置文件指针位置
        
        boolean b1 = ra2.readBoolean();
        System.out.println(b1);
    }
}

2、例题:将一个文件复制三遍

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

public class CopyFile {
    public static void main(String[] args) throws IOException {
        File file = new File("许巍 - 曾经的你.mp3");
        RandomAccessFile ra = new RandomAccessFile(file, "rw");
        for (int i = 1; i <= 3; i++) {
            File f = new File(i+".许巍 - 曾经的你.mp3");
            RandomAccessFile ra1 = new RandomAccessFile(f, "rw");
            int len=0;
            byte[] bytes = new byte[1024 * 1024];
            while ((len=ra.read(bytes))!=-1){
                ra1.write(bytes,0,len);
            }
            ra1.close();
            ra.seek(0);
        }
        ra.close();
    }
}

六、Properties

属性:集合,经常用来读写配置文件,属于双列集合,规定键只能是String类型
用此集合特有方法来存储键值对:
pro.setProperty(key,value);
获取键值:
pro.getProperty(key);
pro.getProperty(key,value);//如果键没有找到对应的值,则返回默认值参数2 
读取配置文件:
pro.load(new FileReader(file));
要求配置文件键值用“=”连接
写配置文件:
pro.store(new FileWriter("文件名"),null);

演示

import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Properties;

public class MyTest5 {
    public static void main(String[] args) throws IOException {
        Properties properties = new Properties();
        properties.setProperty("a","aaa");//添加键值对
        String a = properties.getProperty("a");//获取键值
        System.out.println(a);
        String s1 = properties.getProperty("b", "bbb");//如果找不到键所对应的值,则返回参2
        System.out.println(s1);

        properties.setProperty("b","bbb");
        //参2表示文件的注释,为null默认为日期
        properties.store(new FileWriter("ab.properties"),null);
        properties.load(new FileReader("ab.properties"));
        System.out.println(properties);//{b=bbb, a=aaa}
    }
}
配置文件内容:
#Thu Jul 25 15:17:20 CST 2019
b=bbb
a=aaa

七、SequenceInputStream

SequenceInputStream 
	表示其他输入流的逻辑串联。
	它从输入流的有序集合开始,并从第一个输入流开始读取,直到到达文件末尾,接着从第二个输入流读取,依次类推,直到到达包含的最后一个输入流的文件末尾为止
	构造方法:
	SequenceInputStream(InputStream s1, InputStream s2) 
	通过记住这两个参数来初始化新创建的 SequenceInputStream(将按顺序读取这两个参数,先读取 s1,然后读取 s2),以提供从此 SequenceInputStream 读取的字节。

	SequenceInputStream(Enumeration<? extends InputStream> e) 
	 通过记住参数来初始化新创建的 SequenceInputStream,该参数必须是生成运行时类型为 InputStream 对象的 Enumeration 型参数(迭代器)。

演示

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.SequenceInputStream;
import java.util.Enumeration;
import java.util.Vector;

public class MergeFile {
    public static void main(String[] args)throws IOException {
        Vector<FileInputStream> vector = new Vector<>();
        for (int i = 1; i <= 5; i++) {
            FileInputStream in = new FileInputStream(i + ".许巍 - 蓝莲花.mp3");
            vector.add(in);//将文件输入流添加到集合
        }
        Enumeration<FileInputStream> elements = vector.elements();//获取迭代器
        SequenceInputStream sIn = new SequenceInputStream(elements);
        FileOutputStream out = new FileOutputStream("1许巍 - 蓝莲花.mp3");
        int len;
        byte[] bytes = new byte[1024 * 1024];
        while ((len=sIn.read(bytes))!=-1){
            out.write(bytes,0,len);
            out.flush();
        }
        sIn.close();//会同时将迭代器中的流关闭
        out.close();
    }
}
发布了55 篇原创文章 · 获赞 23 · 访问量 4349

猜你喜欢

转载自blog.csdn.net/y_Engineer/article/details/97264984