写在前面

java学习笔记 七——IO

笔记

流是一个抽象、动态的概念,是一连串连续动态的数据集合

mark

I/O流的几个核心类或接口:(5个类3个接口)

说明
File 文件流
InputStream 字节输入流
OutputStream 字节输出流
Reader 字符输入流
Writer 字符输出流
Closeable 关闭流接口
Flushable 刷新流接口
Serializable 序列化接口

按照流向分类:

  • 输入流:数据源到程序(InputStream、Reader)
  • 输出流:程序到目的地(OutputStream、Writer)

按照功能分:

  • 节点流:可以直接从数据源或目的地读写数据

  • 处理流(包装流):不直接连接到数据源或目的地,是其他流进行封装

    节点流与处理流:

    1. IO流所有操作都是通过节点流进行的
    2. 处理流可以对其他流进行处理

按照数据分:

  • 字节流:按照字节读取数据的(InputStream、OutputStream)
  • 字符流:按照字符读取数据(Reader、Writer)。其底层还是基于字节流操作,自动搜寻指定码表

File

相对路径是相对于工程文件夹。

File常用方法:

基本信息(文件和路径):
package cn.xgblack.io;

import java.io.File;

/**
 * 名称和路径
 */
public class FileDemo03 {
    public static void main(String[] args) {
        File src = new File("IO.png");

        System.out.println("名称:" + src.getName());
        System.out.println("路径:" + src.getPath());
        System.out.println("绝对路径:" + src.getAbsolutePath());

        System.out.println("父路径:" + src.getParent());//根据定义的是相对路径还是绝对路径结果不同,如果父路径没有则返回null
        //System.out.println("父对象:" + src.getParentFile().getName());//此处父对象为空,所以运行的话会报空指针异常
    }
}

mark

文件状态:
package cn.xgblack.io;

import java.io.File;

/**
 * 文件状态
 * 1、不存在exists
 * 2、存在
 *      文件:isFile
 *      文件夹:isDirectory
 */
public class FileDemo04 {
    public static void main(String[] args) {
        File src = new File("IO.png");
        System.out.println("是否存在:" + src.exists());
        System.out.println("是否为文件:" + src.isFile());
        System.out.println("是否为文件夹:" + src.isDirectory());

        src = new File("123/IO.png");
        System.out.println("----------------------------");
        System.out.println("是否存在:" + src.exists());
        System.out.println("是否为文件:" + src.isFile());
        System.out.println("是否为文件夹:" + src.isDirectory());

        //常用文件操作
        src = new File("xxx");
        if (!src.exists() || src == null){
            System.out.println("文件不存在");
        }else{
            if (src.isFile()){
                System.out.println("文件操作");
            }else {
                System.out.println("文件夹操作");
            }
        }


    }
}

其他信息:
  • length()获取文件长度(long类型),如果不存在或者是文件夹则返回0

  • createFile()创建文件(不能创建文件夹)前提是文件不存在才能创建 (创建文件时,与系统关键词冲突也无法创建)

  • delete()删除已经存在的文件

    File src = new File("D:/Code/IdeaJava/javaStudyIO/IO.txt");
          boolean flag = src.createNewFile();
          System.out.println(flag);
          flag = src.delete();
          System.out.println(flag);
    

文件夹:

  • mkdir()确保上级目录存在,不存在创建失败

  • mkdirs()上级目录可以不存在,不存在统一来创建

    File dir = new File("D:/Code/IdeaJava/javaStudyIO/src/dir/test");
    
          boolean flag = dir.mkdir();
          System.out.println(flag);
          flag = dir.mkdirs();
          System.out.println(flag);
    
  • list()列出下一级名称(返回String数组)

  • listFiles()列出下一级File对象(返回File对象数组)

    //列出下级名称
          String[] subName = dir.list();
          for(String s:subName){
              System.out.println(s);
          }
    
          System.out.println("###################");
    
          //下级对象
          File[] subFiles = dir.listFiles();
          for (File s:subFiles
               ) {
              System.out.println(s.getAbsolutePath());
          }
    

递归打印子孙级目录:

package cn.xgblack.io;

import java.io.File;

/**
 *递归
 * 打印子孙级目录
 */
public class DirDemo03 {
    public static void main(String[] args) {
        File dir = new File("D:/Code/IdeaJava/javaStudyIO");
        printName(dir,0);

    }

    public static void printName(File src,int deep){
        //控制层次感
        for(int i = 0;i < deep;i++){
            System.out.print("-");
        }
        //打印名称
        System.out.println(src.getName());
        if(src ==null||!src.exists()){//递归头
            return;
        }else if(src.isDirectory()){
            for(File s:src.listFiles()){
                printName(s,deep + 1);
            }
        }
    }


}

mark

递归统计文件夹的大小:

package cn.xgblack.io;

import java.io.File;

/**
 *统计文件夹的大小
 */
public class DirDemo04 {
    public static void main(String[] args) {
        File dir = new File("D:/Code/IdeaJava/javaStudyIO");
        count(dir);
        System.out.println(len);

    }
    private static long len = 0;

    public static void count(File src){

        //获取大小
        if (src != null&&src.exists()){
            if(src.isFile()){
                len += src.length();
            }else{
                for(File s:src.listFiles()){
                    count(s);
                }
            }
        }
    }


}

使用面相对象统计文件夹的大小
package cn.xgblack.io;

import java.io.File;

/**
 * 使用面向对象统计文件夹的大小
 */
public class DirCount {
    private long len;//大小
    private String path;//文件夹
    private File src;//源

    private int fileSize = -1;//文件的个数(不包含自身)
    private int dirSize = 1;//文件夹的个数(不包含自身)

    public DirCount(String path) {
        this.path = path;
        this.src = new File(path);

        count(this.src);
    }

    private void count(File src){

        //获取大小
        if (src != null&&src.exists()){
            if(src.isFile()){
                len += src.length();
                this.fileSize++;
            }else{
                this.dirSize++;
                for(File s:src.listFiles()){
                    count(s);
                }
            }
        }
    }

    public long getLen() {
        return len;
    }

    public int getFileSize() {
        return fileSize;
    }
    public int getDirSize() {
        return dirSize;
    }

    public static void main(String[] args) {
        DirCount dir = new DirCount("D:/Code/IdeaJava/javaStudyIO");
        System.out.println(dir.getLen() + "-->" + dir.getFileSize() + "-->" + dir.getDirSize());

        DirCount dir2 = new DirCount("D:/Code/IdeaJava/javaStudyIO/src");
        System.out.println(dir2.getLen() + "-->" + dir2.getFileSize() + "-->" + dir2.getDirSize());

    }


}

过滤器
  • FileFilter对File对象进行过滤
  • FileFilter

过滤器只有接口,没有实现类,实现类需要自己写,并重写accept方法,定义过滤规则。

import java.io.FileFilter;

/**
 * @author 小光
 * @date 2019/4/29 16:51
 * className: FileFilterImpl
 * description:
 * ***************************************************************************
 * Copyright(C),2018-2019,https://blog.xgblack.cn  .All rights reserved.
 * ***************************************************************************
 */
public class FileFilterImpl implements FileFilter {
    @Override
    public boolean accept(File pathname) {
        if (pathname.isDirectory()){
            return true;
        }else {
            return pathname.getName().toLowerCase().endsWith(".java");
        }
    }
}
public class RecursiveSearchFile {
    public static void main(String[] args) {
        File src = new File("./");
        printDir(src,0);
    }

    public static void printDir(File dir,int deep){

        for (int i = 0; i < deep; i++) {
            System.out.print("-");
        }
        //使用FileFilter过滤器过滤
        File[] files = dir.listFiles(new FileFilterImpl());
        if (dir.isDirectory()){
            for (File f:files){
                //if (f.getName().toLowerCase().endsWith(".java")){
                    System.out.println(f.getName());
                //}
                printDir(f,deep + 1);
            }

        }
    }
}

直接使用匿名内部类:

package cn.xgblack.io;

import java.io.File;
import java.io.FileFilter;

/**
 * @author 小光
 * @date 2019/4/29 13:29
 * className: RecursiveSearchFile02
 * description: 递归搜索文件
 * ***************************************************************************
 * Copyright(C),2018-2019,https://blog.xgblack.cn  .All rights reserved.
 * ***************************************************************************
 */
public class RecursiveSearchFile02 {
    public static void main(String[] args) {
        File src = new File("./");
        printDir(src,0);
    }

    public static void printDir(File dir,int deep){
        for (int i = 0; i < deep; i++) {
            System.out.print("-");
        }
        //传递过滤器对象,使用匿名内部类
        File[] files = dir.listFiles(new FileFilter() {
            @Override
            public boolean accept(File pathname) {
                return pathname.isDirectory() || pathname.getName().toLowerCase().endsWith(".java");
            }
        });
        for (File f:files){
            if (f.isDirectory()){
                printDir(f,deep + 1);
            }else {
                System.out.println(f.getName());
            }
        }



    }
}

编码解码

字节-->字符:解码;字符–>字节:编码。

getBytes()方法,获取字符串的字节(返回byte[])

操作步骤

文件字节输入流:
  1. 创建源
  2. 选择流
  3. 操作
  4. 释放资源
/**
 * Copyright(C),2018-2019,http://blog.xgblack.cn
 * FileName:    IOTest01
 * Author:      小光
 * Date:        2019/4/24 17:52
 * Description: 标准步骤
 */
package cn.xgblack.iostudy;

import java.io.*;

public class IOTest02 {
    public static void main(String[] args) {
        //1.创建源
        File src = new File("abc.txt");
        //2.选择流
        InputStream is = null;
        try {
            is = new FileInputStream(src);
            //3.操作(读取)
            int temp;
            //当没有读取到时返回-1
            while ((temp = is.read()) != -1){
                System.out.print((char)temp);
            }


        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            //4.释放资源
            //is用到了,才进行释放
            if (null != is){
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
/**
 * Copyright(C),2018-2019, 小光 http://blog.xgblack.cn
 * FileName:    IOTest01
 * Author:      xg
 * Date:        2019/4/24 17:52
 * Description: 标准步骤:分段读取
 */
package cn.xgblack.iostudy;

import java.io.*;

public class IOTest03 {
    public static void main(String[] args) {
        //1.创建源
        File src = new File("abc.txt");
        //2.选择流
        InputStream is = null;
        try {
            is = new FileInputStream(src);
            //3.操作(分段读取)
            byte[] flush = new byte[1024];//缓冲容器
            int len = -1;
            //当没有读取到时返回-1
            while ((len = is.read(flush)) != -1){
             //字节数组-->字符串(解码)
                String str = new String(flush, 0, len);
                System.out.print(str);
            }


        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            //4.释放资源
            //is用到了,才进行释放
            if (null != is){
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
文件字节输出流:
/**
 * Copyright(C),2018-2019,http://blog.xgblack.cn
 * FileName:    IOTest04
 * Author:      小光
 * Date:        2019/4/24 20:31
 * Description: 文件字节输出流
 */
package cn.xgblack.iostudy;

import java.io.*;

public class IOTest04 {
    public static void main(String[] args) {
        //1.创建源
        File desk = new File("desk.txt");
        //选择流
        OutputStream os = null;
        try {
            //os = new FileOutputStream(desk);
            os = new FileOutputStream(desk,true);//在文件内末尾追加内容
            //操作(写)
            String msg = "i am study IO\r\n";
            byte[] datas = msg.getBytes();//字符串-->字节数组(编码)
            os.write(datas,0,datas.length);
            os.flush();
        }catch (FileNotFoundException e){
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //释放资源
            if(os != null){
                try {
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
实现文件的拷贝:
/**
 * Copyright(C),2018-2019,http://blog.xgblack.cn
 * FileName:    Copy
 * Author:      小光
 * Date:        2019/4/24 21:06
 * Description: 使用文件字节输入流和字节输出流达到文件拷贝
 */
package cn.xgblack.iostudy;

import java.io.*;

public class Copy {
    public static void main(String[] args) {
        copy("pic.png","picCopy.png");
    }

    public static void copy(String srcPath,String deskPath){
        //创建源
        File src = new File(srcPath);
        File desk = new File(deskPath);
        //选择流
        InputStream is = null;
        OutputStream os = null;
        //操作:读取
        try {
            is = new FileInputStream(src);//源文件
            os = new FileOutputStream(desk);//目标文件

            byte[]flush = new byte[1024];//缓存容器
            int len = -1;
            while ((len = is.read(flush)) != -1){
                //操作:写入
                os.write(flush,0,len);
            }
            os.flush();

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            //释放
            try {
                if(os != null) {
                    os.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if(is != null) {
                    is.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

}
文件字符输入输出流:

通过字符的方式操作文件,仅适合于字符文件

package cn.xgblack.iostudy;

import java.io.*;

/**
 * @author 小光
 * @date 2019/4/27 15:19
 * Copyright(C),2018-2019,http://blog.xgblack.cn
 * className: RWCopy
 * description: 字符输入输出流复制文件
 */
public class RWCopy {
    public static void main(String[] args) {
        copyFile("desk.txt","deskCopy.txt");
    }

    public static void copyFile(String srcPath,String deskPath){
        //创建源
        File src = new File(srcPath);
        File desk = new File(deskPath);
        //选择流
        Reader reader = null;
        Writer writer = null;
        try {
            reader = new FileReader(src);
            writer = new FileWriter(desk);

            char[] datas = new char[10];
            int len = -1;
            while ((len = reader.read(datas)) != -1){
                writer.write(datas,0,datas.length);
            }
            writer.flush();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                if (writer != null) {
                    writer.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (reader != null) {
                    reader.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

Properties属性集

Properties集合是一个键与值都为String的键值对集合,有点类似于Map。Properties可以保存到流中或者从流中加载。

方法:store()与load()

  • void store(Writer writer, String comments) 或者void store(OutputStream out, String comments)
  • void load(Reader reader) 或者void load(InputStream inStream) 如果不想读取文本中的某条数据,可以在数据前面加一个#
package cn.xgblack.iostudy;

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

/**
 * @author 小光
 * @date 2019/4/29 22:58
 * className: Demo01Properties
 * description:
 * ***************************************************************************
 * Copyright(C),2018-2019,https://blog.xgblack.cn  .All rights reserved.
 * ***************************************************************************
 */
public class Demo01Properties {
    public static void main(String[] args) {
        show03();
    }

    /**
     * @author      小光
     * @date        2019/4/30 17:50
     * description  键值对文件读取到集合中
     * @param       []
     */
    private static void show03() {
        //创建一个properties对象
        Properties prop = new Properties();
        //调用load方法
        try {
            prop.load(new FileReader("prop.txt"));
            Set<String> set = prop.stringPropertyNames();
            for (String key:set
                 ) {
                String value = prop.getProperty(key);
                System.out.println(key + "=" + value);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    /**
     * @author      小光
     * @date        2019/4/30 18:09
     * description  //TODO
     * @param       []
     * @return      void
     */
    private static void show02() {
        Properties prop = new Properties();
        prop.setProperty("赵丽颖", "160");
        prop.setProperty("迪丽热巴", "185");
        prop.setProperty("古力娜扎", "180");

        //OutputStream os = new FileOutputStream("prop.txt");

        try (Writer writer = new FileWriter("prop.txt")){
            prop.store(writer,"save data");
        } catch (IOException e) {
            e.printStackTrace();
        }

    //    try {
    //        prop.store(new FileOutputStream("prop2.txt"),"save data2");
    //    } catch (IOException e) {
    //        e.printStackTrace();
    //    }

    }

    private static void show01() {
        Properties prop = new Properties();
        prop.setProperty("赵丽颖", "160");
        prop.setProperty("迪丽热巴", "185");
        prop.setProperty("古力娜扎", "180");

        Set<String> set = prop.stringPropertyNames();

        for (String key:set){
            String value = prop.getProperty(key);
            System.out.println(key + value);
        }
    }
}

缓冲流

字节缓冲输出流
  • BufferedOutputStream(OutputStream out)
  • BufferedOutputStream(OutputStream out, int size)
package cn.xgblack.otherio;

import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

/**
 * @author 小光
 * @date 2019/5/1 9:56
 * className: Demo02BufferedStream
 * description: 字节缓冲输出流
 * ***************************************************************************
 * Copyright(C),2018-2019,https://blog.xgblack.cn  .All rights reserved.
 * ***************************************************************************
 */
public class Demo02BufferedOutputStream {
    public static void main(String[] args) {
        //创建FileOutputStream对象,并指定路径

        try (OutputStream os = new FileOutputStream("src/cn/xgblack/otherio/buffered01.txt");
             BufferedOutputStream bos = new BufferedOutputStream(os)
        ){
            bos.write("这是字节缓冲输出流的写入的文字".getBytes());
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}
字节输入缓冲流

使用方法步骤类似

复制文件:

package cn.xgblack.otherio;


import java.io.*;

/**
 * @author 小光
 * @date 2019/5/1 10:35
 * className: BufferedCopy
 * description: 字节缓冲流复制文件
 * ***************************************************************************
 * Copyright(C),2018-2019,https://blog.xgblack.cn  .All rights reserved.
 * ***************************************************************************
 */
public class BufferedCopy {
    public static void main(String[] args) {
        copy("IO.png","src/cn/xgblack/otherio/IO-bufferedCopy.png");
    }

    /**
     * @author      小光
     * @date        2019/5/1 10:43
     * description  使用缓冲流复制文件
     * @param       [srcPath , destPath]
     */
    private static void copy(String srcPath, String destPath) {
        try (
                FileInputStream fis = new FileInputStream(srcPath);
                FileOutputStream fos = new FileOutputStream(destPath);
                BufferedInputStream bis = new BufferedInputStream(fis);
                BufferedOutputStream bos = new BufferedOutputStream(fos)
        ) {
            byte[] bytes = new byte[1024];
            int len = 0;
            while ((len = bis.read(bytes)) != -1){
                bos.write(bytes,0,len);
            }
            bos.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
字符缓冲流

特有的成员方法:

  • void newLine() 写入一个行分隔符。会自动根据操作系统不同获取不同的行分割符
  • void readLine()读取一个文本行。返回包含该行内容的字符串,不包含任何终止符,如果已经达到流末尾,返回null

转换流

  • InputStreamReader字节流通向字符流的的桥梁,可以查询指定码表。(解码)
    • OutputStreamWriter(OutputStream out)

    • OutputStreamWriter(OutputStream out, String charsetName)

    charsetName指的是编码表名称,utf-8/UTF-8,gbk/GBK等

  • OutputStreamWriter字符流通向字节流的桥梁,,可以查询指定码表。(编码)

package cn.xgblack.otherio;

import java.io.*;

/**
 * @author 小光
 * @date 2019/5/1 13:27
 * className: DemoOutputStreamWriter
 * description:
 * ***************************************************************************
 * Copyright(C),2018-2019,https://blog.xgblack.cn  .All rights reserved.
 * ***************************************************************************
 */
public class DemoOutputStreamWriter {
    public static void main(String[] args) {
        //writeUtf8();
        readGbk();
    }

    private static void readGbk() {
        try (
                InputStreamReader isr = new InputStreamReader(new FileInputStream("src/cn/xgblack/otherio/gbk.txt"), "GBK");
        ) {
            int len = 0;
            char[] flush = new char[1024];
            while ((len = isr.read(flush)) != -1){
                System.out.println(new String(flush,0,len));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private static void writeUtf8() {
        try(
                //OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("src/cn/xgblack/otherio/utf-8.txt"),"UTF-8");
                //OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("src/cn/xgblack/otherio/utf-8.txt"));
                OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("src/cn/xgblack/otherio/gbk.txt"),"GBK");
        ){
            osw.write("你好");
            osw.flush();
        }catch (IOException e){
            e.printStackTrace();
        }
    }


}
package cn.xgblack.otherio;

import java.io.*;

/**
 * @author 小光
 * @date 2019/5/1 13:50
 * className: ChangeGbk
 * description: 通过转换流进行文件编码的转换
 * ***************************************************************************
 * Copyright(C),2018-2019,https://blog.xgblack.cn  .All rights reserved.
 * ***************************************************************************
 */
public class ChangeGbk {
    public static void main(String[] args) {
        utfToGbk("src/cn/xgblack/otherio/utf8test.txt", "src/cn/xgblack/otherio/gbktest.txt");
    }

    private static void utfToGbk(String srcPath, String destPath) {
        try (
                InputStreamReader isr = new InputStreamReader(new FileInputStream(srcPath), "utf-8");
                OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(destPath), "GBK")
        ) {
            char[] flush = new char[1024];
            int len = 0;
            while ((len = isr.read(flush)) != -1) {
                osw.write(flush, 0, len);
            }
            osw.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

序列化流与反序列化流

前提:类必须实现Serializable

  • ObjectOutputStream对象的序列化流

    特有的成员方法:void writeObject(Object obj)

  • ObjectIutputStream对象的反序列化流

    特有的成员方法:void readObject(Object obj)

package cn.xgblack.otherio;

import java.io.*;

/**
 * @author 小光
 * @date 2019/5/1 14:21
 * className: DemoObjectOutputStream
 * description:
 * ***************************************************************************
 * Copyright(C),2018-2019,https://blog.xgblack.cn  .All rights reserved.
 * ***************************************************************************
 */
public class DemoObjectOutputStream {
    public static void main(String[] args) {
        //objectOutputStream();
        objectItputStream();
    }

    private static void objectItputStream() {
        try (
                ObjectInputStream ois = new ObjectInputStream(new FileInputStream("src/cn/xgblack/otherio/objcet.txt"))
        ) {
            Object obj = ois.readObject();
            System.out.println(obj);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    private static void objectOutputStream() {
        try (
                ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("src/cn/xgblack/otherio/objcet.txt"))
        ) {
            oos.writeObject(new Person("小光",18));
            oos.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

transient瞬态关键字

被transient关键字修饰的成员变量无法被序列化,相当于static,但是有没有static静态的作用。

序列号冲突异常

如果序列化之后,对类有所修改,直接进行反序列化,会产生序列化冲突异常。因为class文件中的序列号变了,所以解决方法就是在类中定义一个不变的序列号。

private static final long serialVersionUID = 1L;

对集合进行序列化与反序列化:

package cn.xgblack.otherio;

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

/**
 * @author 小光
 * @date 2019/5/1 15:04
 * className: DemoListObject
 * description:
 * ***************************************************************************
 * Copyright(C),2018-2019,https://blog.xgblack.cn  .All rights reserved.
 * ***************************************************************************
 */
public class DemoListObject {
    public static void main(String[] args) {
        List<Person> list = new ArrayList<>();
        list.add(new Person("张三", 15));
        list.add(new Person("李四", 18));
        list.add(new Person("王五", 21));

        try (
                ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("src/cn/xgblack/otherio/objcetList.txt"));
                ObjectInputStream ois = new ObjectInputStream(new FileInputStream("src/cn/xgblack/otherio/objcetList.txt"))
        ) {
            oos.writeObject(list);


            Object object = ois.readObject();
            ArrayList<Person> list2 = (ArrayList<Person>)object;
            for(Person p:list2){
                System.out.println(p);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

打印流

  1. printStream只负责数据输出,不负责数据读取
  2. 与其他输出流不同,printStream永远不会抛出IoException
  3. 有特有的方法,print,println

注意:

  • 如果使用继承自父类的write方法写数据,那么查看数据的时候会查编码表(97->a)
  • 如果使用自己特有的方法print,println写数据就会原样输出(97->97)
package cn.xgblack.otherio;

import java.io.FileNotFoundException;
import java.io.PrintStream;

/**
 * @author 小光
 * @date 2019/5/1 15:23
 * className: DemoPrintStream
 * description:
 * ***************************************************************************
 * Copyright(C),2018-2019,https://blog.xgblack.cn  .All rights reserved.
 * ***************************************************************************
 */
public class DemoPrintStream {
    public static void main(String[] args) {
        try (
                PrintStream ps = new PrintStream("src/cn/xgblack/otherio/print.txt")
        ) {
            ps.write(97);
            ps.print(97);
            ps.flush();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }
}

改变输出语句流向:

package cn.xgblack.otherio;

import java.io.FileNotFoundException;
import java.io.PrintStream;

/**
 * @author 小光
 * @date 2019/5/1 15:27
 * className: DemoPrint
 * description:
 * ***************************************************************************
 * Copyright(C),2018-2019,https://blog.xgblack.cn  .All rights reserved.
 * ***************************************************************************
 */
public class DemoPrint {
    public static void main(String[] args) {
        System.out.println("控制台输出的语句");

        try (
                PrintStream ps = new PrintStream("src/cn/xgblack/otherio/printDemo.txt")
        ) {
            //改变输出语句的流向
            System.setOut(ps);
            System.out.println("我在哪输出呢");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }
}

道也者,不可须臾离者也,可离非道也。