IO流(下)

222 阅读5分钟

转换流(处理流的一种)

1.转换流:(属于字符流)

InputStreamReader:将一个字节的输入流转换为字符的输入流

OutputStreamWriter:将一个字符的输出流转换为字节的输出流

2.作用:提供字节流和字符流之间的转换

3.解码:字节,字节数组---->字符,字符数组

编码:字符,字符数组---->字节,字节数组

4.字符集

测试InputStreamReader的使用

//测试InputStreamReader的使用,实现字节的输入流到字符的输入流之间的转换
public void test() throws IOException {
    FileInputStream fis = new FileInputStream("hello.txt");
    InputStreamReader isr = new InputStreamReader(fis);//使用系统默认的字符集
    //参数2指明了字符集,具体使用哪种,取决于文件hello.txt保存时使用的字符集
    InputStreamReader isr1 = new InputStreamReader(fis,"UTF-8");//使用系统默认的字符集

    char[]cbuf=new char[20];
    int len;
    while((len=isr.read(cbuf))!=-1){
        String str = new String(cbuf,0,len);
        System.out.println(str);
    }
    isr.close();

综合使用InputStreamReader和OutputStreamWriter

@Test
public void test1() throws IOException {
    //1.造文件,造流
    File file = new File("hello.txt");
    File file1 = new File("hello-gbk.txt");
    FileInputStream fis = new FileInputStream(file);
    FileOutputStream fos = new FileOutputStream(file1);
    InputStreamReader isr = new InputStreamReader(fis,"utf-8");
    OutputStreamWriter osw = new OutputStreamWriter(fos,"gbk");
    //2.读写过程
    char[] cbuf = new char[20];
    int len;
    while((len=isr.read(cbuf))!=-1){
        osw.write(cbuf,0,len);
    }
    //3.资源关闭
    isr.close();
    osw.close();

image.png

其他流的使用

1.标准的输入,输出流

2.打印流

3.数据流

1.标准的输入,输出流

System.in:标准的输入流,默认从键盘输入 System.out:标准的输入流,默认从控制台输出

1.2

System类的setIn(InputStream is)/setOut(PrintStream ps)方式重新指定输入和输出的流

1.3练习:

从键盘读取字符串,要求将读取到的整行字符串转化为大写输出,然后继续进行输入操作。 直到输入"e"或"exit",退出程序

public static void main(String[] args) throws IOException {
    //使用System.in(输入流)实现。System.in--->转换流--->BufferedReader的readLine()
    InputStreamReader isr = new InputStreamReader(System.in);
    BufferedReader br = new BufferedReader(isr);

    while(true){
        System.out.println("请输入字符串:");
        String data = br.readLine();
        if("e".equalsIgnoreCase(data)||"exit".equalsIgnoreCase(data)){
            System.out.println("程序结束");
            break;
        }
        String s = data.toUpperCase();
        System.out.println(s);
    }
    br.close();

2.打印流

image.png 2.打印流:PrintStream和PrintWriter

2.1 提供了一系列重载的print()和println

2.2作用:可以将控制台呈现的东西打印在文件上

3.数据流

3.1 DataInputStream和DataOutputStream

image.png 3.2作用:用于读取或写出基本数据类型的变量或字符串

练习:将内存中的字符串,基本数据类型的变量写出到文件中
//注意:应该使用try-catch-finally(这里偷懒直接抛掉了)
@Test
public void test2() throws IOException {
    DataOutputStream dos = new DataOutputStream(new FileOutputStream("data.txt"));
    dos.writeUTF("黄某");
    dos.flush();//刷新操作,将内存中的数据写入文件
    dos.writeInt(19);
    dos.flush();
    dos.writeBoolean(true);
    dos.flush();
    dos.close();
}
@Test
//将文件中存储的基本数据类型变量和字符串读取到内存中,保存在变量中
//注意:读取不同类型的数据的顺序要与当初写入文件时,保存数据的顺序一致
public void test3() throws IOException {
    DataInputStream dis = new DataInputStream(new FileInputStream("data.txt"));
    String s = dis.readUTF();
    int i = dis.readInt();
    boolean b = dis.readBoolean();
    System.out.println(s+" "+i+" "+b);
    dis.close();
}

对象流

image.png

image.png

对象流的使用

1.ObjectInputStream和ObjectOutputStream

2.作用:用于存储和读取基本数据类型或对象的处理流。 它的强大之处就是可以把Java中的对象写入到数据源中,也能把对象从数据源中还原回来

public void test4() throws IOException {
    /*
    序列化过程:将内存中的java对象保存到磁盘中或通过网络传输出去
    使用ObjectOutputStream来实现
     */
    ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("object.txt"));//生成的文件要通过反序列化才能查看
    oos.writeObject(new String("我爱北京天安门"));
    oos.flush();//刷新操作
    oos.close();
}
@Test
public void test5() throws IOException, ClassNotFoundException {
    //反序列化过程,将磁盘文件中的对象还原为内存中的一个java对象
    //使用ObjectInputStream来实现
    ObjectInputStream ois = new ObjectInputStream(new FileInputStream("object.txt"));
    Object o = ois.readObject();
    System.out.println(o);
    ois.close();
}
public class Person implements Serializable {
    /*Person类需要满足如下的要求,方可序列化
    1.需要实现接口SerializableSerializable

    2.需要类提供一个全局常量:serialVersionUID
    3.除了当前类Person类需要实现SerializableSerializable
接口之外,还必须保证其内部所有属性也必须是可序列化的。(默认情况下,基本数据类型是可序列化的),即Person内部的自定义类的属性所属的类也要实现序列化。
	补充:序列化和反序列化不能修饰static和transient修饰的成员变量
     */
    public static final long serialVersionUID = 6433858223774886977L;

serialVersionUID的理解

image.png 对于序列化后而还没反序列化时,此时serialVersionUID可以作为电脑对Person类的识别码,若你在中途将Person内部进行了修改,那么电脑还可以通过serialVersionUID对你做出的修改做出反应。若没有serialVersionUID,则无法识别

随机存取文件流

image.png

image.png

image.png

/*RandomAccessFile的使用
1.RandomAccessFile直接继承于java.lang.Object类,实现了DataInput和DataOutput
2.RandomAccessFile既可以作为一个输入流,也可以作为一个输出流,但是要造2个对象
3.如果RandomAccessFile作为输出流时,写出到的文件如果不存在,则自动创建。若存在,则会对原有文件进行覆盖(默认情况下,从头开始覆盖)
4.可以通过相关的操作,使用RandomAccessFile实现插入效果
 */
public class RandomAccessFileTest {
    @Test
    public void test() throws IOException {
        RandomAccessFile raf = new RandomAccessFile(new File("小哀.jpg"),"r");
        RandomAccessFile raf1 = new RandomAccessFile(new File("小哀3.jpg"),"rw");

        byte[]buffer = new byte[1024];
        int len;
        while((len=raf.read(buffer))!=-1){
            raf1.write(buffer,0,len);
        }
        raf.close();
        raf1.close();

    }
    @Test
    public void test2() throws IOException {//使用RandomAccessFile实现覆盖效果
        RandomAccessFile raf = new RandomAccessFile("hello.txt","rw");
        raf.seek(3);//默认为0。将指针调到角标为3的位置,abcdefghijklmn-->abcxyzghijklmn
        raf.write("xyz".getBytes());//hello.txt中的abcdefghijklmn-->xyzdefghijklmn
        raf.close();
    }
    //使用RandomAccessFile实现插入效果
    @Test
    public void test3() throws IOException {
        RandomAccessFile raf = new RandomAccessFile("hello.txt","rw");
        raf.seek(3);//将指针调到角标为3的位置
        //保存指针3后面的所有数据到StringBuilder中
        StringBuilder builder = new StringBuilder((int) new File("hello.txt").length());
        byte[]buffer=new byte[20];
        int len;
        while((len=raf.read(buffer))!=-1){
            builder.append(new String(buffer,0,len));
        }
        //调回指针,写入"xyz"
        raf.seek(3);
        raf.write("xyz".getBytes());
        //将StringBuilder中的数据写入到文件中
        raf.write(builder.toString().getBytes());
        raf.close();
    }

image.png

image.png

image.png

image.png

image.png