12 IO流

File类:
构造方法
    * File(String pathname):根据一个路径得到File对象
    * File(String parent, String child):根据一个目录和一个子文件/目录得到File对象
    * File(File parent, String child):根据一个父File对象和一个子文件/目录得到File对象

创建功能
    * public boolean createNewFile():创建文件 如果存在这样的文件,就不创建了,返回false
    * public boolean mkdir():创建文件夹 如果存在这样的文件夹,就不创建了
    * public boolean mkdirs():创建文件夹,如果父文件夹不存在,会帮你创建出来

重命名和删除功能:
    * public boolean renameTo(File dest):把文件重命名为指定的文件路径
    * public boolean delete():删除文件或者文件夹
    重命名注意事项
    * 如果路径名相同,就是改名。
    * 如果路径名不同,就是改名并剪切。
    删除注意事项:
    * Java中的删除不走回收站。
    * 要删除一个文件夹,请注意该文件夹内不能包含文件或者文件夹


判断功能:

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

public class Demo1_File {
/*    判断功能
    * public boolean isDirectory():判断是否是目录
    * public boolean isFile():判断是否是文件
    * public boolean exists():判断是否存在
    * public boolean canRead():判断是否可读  
    * public boolean canWrite():判断是否可写
    * public boolean isHidden():判断是否隐藏*/
    public static void main(String[] args) throws IOException {
        File file = new File("aaa.txt");
//        System.out.println(file.createNewFile());
        file.setReadable(false);
        System.out.println(file.canRead());//true  //windowa系统所有文件都是可读的
    }
}
View Code


获取功能:
    * public String getAbsolutePath():获取绝对路径
    * public String getPath():获取路径  构造方法中传入的路径
    * public String getName():获取名称  文件或文件夹
    * public long length():获取长度。字节数
    * public long lastModified():获取最后一次的修改时间,毫秒值
    * public String[] list():获取指定目录下的所有文件或者文件夹的名称数组
    * public File[] listFiles():获取指定目录下的所有文件或者文件夹的File数组


文件名称过滤器:
   

    String[] arr = file.list(new FilenameFilter() {
            @Override
            public boolean accept(File dir, String name) {
                File file = new File(dir,name);
                return file.isFile() && file.getName().endsWith(".jpg");
            }
        });
        for (String string : arr) {
            System.out.println(string);
        }


IO流
    * IO流用来处理设备之间的数据传输
    * Java对数据的操作是通过流的方式
    * Java用于操作流的类都在IO包中
    * 流按流向分为两种:输入流,输出流。
    * 流按操作类型分为两种:
        * 字节流 : 字节流可以操作任何数据,因为在计算机中任何数据都是以字节的形式存
储的
        * 字符流 : 字符流只能操作纯字符数据,比较方便。
IO流常用父类
    * 字节流的抽象父类:
        * InputStream
        * OutputStream
    * 字符流的抽象父类:
        * Reader
        * Writer    

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class Demo1_FileInputStream {

    public static void main(String[] args) throws IOException {
        FileInputStream fInputStream = new FileInputStream("a.txt");//创建一个文件

输入流对象
        int b;
        while((b=fInputStream.read())!=-1) {//将每次读到的字节赋值给b并判断是否是-1
            System.out.println(b);//打印每一个字节
        }
        fInputStream.close();//关闭流释放资源
    }

}


read()方法读取的是一个字节,为什么返回是int,而不是byte
 
    因为字节输入流可以操作任意类型的文件,比如图片音频等,这些文件底层都是以二进制形式的
存储的,如果每次读取都返回byte,有可能在读到中间的时候遇到111111111(-1的补码)
    那么这11111111是byte类型的-1,我们的程序是遇到-1就会停止不读了,后面的数据就读不到了,
所以在读取的时候用int类型接收,会在其前面补上24个0凑足4个字节,如果是11111111,那么byte类型的
-1就变成int类型的255了这样可以保证整个数据读完,而结束标记的-1就是int类型


FileOutputStream
write()一次写出一个字节
*
        FileOutputStream fos = new FileOutputStream("bbb.txt");    //如果没有bbb.txt,
会创建出一个
        //fos.write(97);                        //虽然写出
的是一个int数,但是在写出的时候会将前面的24个0去掉,所以写出的是一个byte
        fos.write(98);
        fos.write(99);
        fos.close();
FileOutputStream追加:

FileOutputStream fos = new FileOutputStream("bbb.txt",true);    //续写第二个参数设为true

字节数组拷贝之available()方法:
    * int read(byte[] b):一次读取一个字节数组
    * write(byte[] b):一次写出一个字节数组
    * available()获取读的文件所有的字节个数
弊端:有可能会内存溢出
    
        FileInputStream fis = new FileInputStream("致青春.mp3");
        FileOutputStream fos = new FileOutputStream("copy.mp3");
        byte[] arr = new byte[fis.available()];                    //

根据文件大小做一个字节数组
        fis.read(arr);                                    

        //将文件上的所有字节读取到数组中
        fos.write(arr);                                    

        //将数组中的所有字节一次写到了文件上
        fis.close();
        fos.close();

定义小数组的标准格式:

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class Demo2_ArrayCopy {

    public static void main(String[] args) throws IOException {
        FileInputStream fInputStream = new FileInputStream("a.txt");
        FileOutputStream fOutputStream = new FileOutputStream("b.txt");
        
        byte[] b = new byte[1024*8];
        int len;
        while((len=fInputStream.read(b))!=-1) {
            fOutputStream.write(b, 0, len);
        }
        fInputStream.close();
        fOutputStream.close();
    }

}


BufferedInputStream和BufferOutputStream拷贝)
缓冲思想
    * 字节流一次读写一个数组的速度明显比一次读写一个字节的速度快很多,
    * 这是加入了数组这样的缓冲区效果,java本身在设计的时候,
    * 也考虑到了这样的设计思想(装饰设计模式),所以提供了字节缓冲区流
BufferedInputStream
    * BufferedInputStream内置了一个缓冲区(数组)
    * 从BufferedInputStream中读取一个字节时
    * BufferedInputStream会一次性从文件中读取8192个, 存在缓冲区中, 返回给程序一个
    * 程序再次读取时, 就不用找文件了, 直接从缓冲区中获取
    * 直到缓冲区中所有的都被使用过, 才重新从文件中读取8192个
BufferedOutputStream
    * BufferedOutputStream也内置了一个缓冲区(数组)
    * 程序向流中写出字节时, 不会直接写到文件, 先写到缓冲区中
    * 直到缓冲区写满, BufferedOutputStream才会把缓冲区中的数据一次性写到文件里
拷贝的代码

        FileInputStream fis = new FileInputStream("xxx.mp3");            //
创建文件输入流对象,关联xxx.mp3
        BufferedInputStream bis = new BufferedInputStream(fis);            //
创建缓冲区对fis装饰
        FileOutputStream fos = new FileOutputStream("copy.mp3");        //
创建输出流对象,关联copy.mp3
        BufferedOutputStream bos = new BufferedOutputStream(fos);        //
创建缓冲区对fos装饰
        
        int b;
        while((b = bis.read()) != -1) {        
            bos.write(b);
        }
        
        bis.close();                        //只关装饰后的对象
即可
        bos.close();
    
小数组的读写和带Buffered的读取哪个更快?
    * 定义小数组如果是8192个字节大小和Buffered比较的话
    * 定义小数组会略胜一筹,因为读和写操作的是同一个数组
    * 而Buffered操作的是两个数组

flush和close方法的区别:
flush()方法:
    用来刷新缓冲区的,刷新后可以再次写出
close()方法:
    用来关闭流释放资源的的,如果是带缓冲区的流对象的close()方法,不但会关闭流,还会再关闭
流之前刷新缓冲区,将缓冲区的字节全部刷新到文件上,再关闭,关闭后不能再写出


字节流读取中文的问题
    字节流在读中文的时候有可能会读到半个中文,造成乱码
字节流写出中文的问题
    字节流直接操作的字节,所以写出中文必须将字符串转换成字节数组
    写出回车换行 write(" ".getBytes());

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

public class Demo_Zh {

    public static void main(String[] args) throws IOException {
        // 字节流写中文
        FileOutputStream fos = new FileOutputStream("z.txt");
        fos.write("字节流写中文".getBytes());
        
        fos.close();
    }

}
View Code


流的标准处理异常代码1.6版本及其以前:

* try finally嵌套

        FileInputStream fis = null;
        FileOutputStream fos = null;
        try {
            fis = new FileInputStream("aaa.txt");
            fos = new FileOutputStream("bbb.txt");
            int b;
            while((b = fis.read()) != -1) {
                fos.write(b);
            }
        } finally {
            try {
                if(fis != null)
                    fis.close();
            }finally {
                if(fos != null)
                    fos.close();
            }
        }
View Code


流的标准处理异常代码1.7版本:

* try close

        try(
            FileInputStream fis = new FileInputStream("aaa.txt");
            FileOutputStream fos = new FileOutputStream("bbb.txt");
            MyClose mc = new MyClose();
        ){
            int b;
            while((b = fis.read()) != -1) {
                fos.write(b);
            }
        }
原理:
    在try()中创建的流对象必须实现了AutoCloseable这个接口,如果实现了,在try后面的{}(读写
代码)执行后就会自动调用流对象的close方法将流关掉 
View Code


通过异或实现给图片加密:

  BufferedInputStream bis = new BufferedInputStream(new FileInputStream
("a.jpg"));
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream
("b.jpg"));
        
        int b;
        while((b = bis.read()) != -1) {
            bos.write(b ^ 123);  // 一个数被另一个数异或2次等于它本身
        }
        
        bis.close();
        bos.close();
View Code


拷贝文件练习:

* 在控制台录入文件的路径,将文件拷贝到当前项目下

        Scanner sc = new Scanner(System.in);
        System.out.println("请输入一个文件路径");
        String line = sc.nextLine();                //将键盘录入的文件

路径存储在line中
        File file = new File(line);                    //封装成

File对象
        FileInputStream fis = new FileInputStream(file);
        FileOutputStream fos = new FileOutputStream(file.getName());
        
        int len;
        byte[] arr = new byte[8192];                //定义缓冲区
        while((len = fis.read(arr)) != -1) {
            fos.write(arr,0,len);
        }
        
        fis.close();
        fos.close();


录入数据拷贝到文件练习:

* 将键盘录入的数据拷贝到当前项目下的text.txt文件中,键盘录入数据当遇到quit时就退出

        Scanner sc = new Scanner(System.in);
        FileOutputStream fos = new FileOutputStream("text.txt");
        System.out.println("请输入:");
        while(true) {
            String line = sc.nextLine();
            if("quit".equals(line))
                break;
            fos.write(line.getBytes()); //字符串写出必须转换为字节数组
            fos.write("
".getBytes());
        }
        
        fos.close();


字符流FileReader
字符流是什么
    * 字符流是可以直接读写字符的IO流
    * 字符流读取字符, 就要先读取到字节数据, 然后转为字符. 如果要写出字符, 需要把字符转
为字节再写出.   

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

public class Demo1_FileReader {

    public static void main(String[] args) throws IOException {
        //字符流FileReader
        FileReader fileReader = new FileReader("a.txt");
        
        int c;
        while((c=fileReader.read()) != -1){ //通过项目默认的码表一次读取一个字符
            System.out.print((char)c);
        }
        fileReader.close();
    }

}


FileWriter:

import java.io.FileWriter;
import java.io.IOException;

public class Demo2_FileWriter {

    public static void main(String[] args) throws IOException {
        //FileWriter
        //你好!a
        FileWriter fileWriter = new FileWriter("b.txt");
        fileWriter.write("你好!");
        fileWriter.write(97);
        
        fileWriter.close();
    }
}


什么情况下使用字符流:
只读或只写时使用字符流
* 字符流也可以拷贝文本文件, 但不推荐使用. 因为读取时会把字节转为字符, 写出时还要把字符转回
字节.
* 程序需要读取一段文本, 或者需要写出一段文本的时候可以使用字符流
* 读取的时候是按照字符的大小读取的,不会出现半个中文
* 写出的时候可以直接将字符串写出,不用转换为字节数组

字符流是否可以拷贝非纯文本的文件:
* 不可以拷贝非纯文本的文件
* 因为在读的时候会将字节转换为字符,在转换过程中,可能找不到对应的字符,就会用?代替,写出的时候
会将字符转换成字节写出去
* 如果是?,直接写出,这样写出之后的文件就乱了

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class Demo3_copy {

    public static void main(String[] args) throws IOException {
        //自定义字符数组的拷贝
/*        FileReader fileReader = new FileReader("a.txt");
        FileWriter fileWriter = new FileWriter("b.txt");
        
        char[] arr = new char[1024];
        int len;
        while((len=fileReader.read(arr))!=-1) {
            fileWriter.write(arr,0,len);
        }
        fileReader.close();
        fileWriter.close();*/
        
        //带缓冲的字符流
        BufferedReader bReader = new BufferedReader(new FileReader("a.txt"));
        BufferedWriter bWriter = new BufferedWriter(new FileWriter("b.txt"));
        
        int len;
        while((len=bReader.read())!=-1) {
            bWriter.write(len);
        }
        bReader.close();
        bWriter.close();
    }
}


readLine()和newLine()方法:

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class Demo4_Line {

    public static void main(String[] args) throws IOException {
        BufferedReader bReader = new BufferedReader(new FileReader("a.txt"));
        BufferedWriter bWriter = new BufferedWriter(new FileWriter("b.txt"));
        
        String line;
        while((line=bReader.readLine())!=null) {
//            System.out.println(line);
            bWriter.write(line);
            bWriter.newLine(); //平台换行符
        }
        bReader.close();
        bWriter.close();
    }

}


将文本反转练习:

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;

public class Demo5_RevCopy {

    public static void main(String[] args) throws IOException {
        // 将文本反转
        BufferedReader bReader = new BufferedReader(new FileReader("a.txt"));
        String line;
        ArrayList<String> aList = new ArrayList<>();
        while((line=bReader.readLine())!=null) {
            aList.add(line);
        }
        bReader.close();
        
        BufferedWriter bWriter = new BufferedWriter(new FileWriter("b.txt"));
        for (int i = aList.size()-1; i >= 0; i--) {
            bWriter.write(aList.get(i));
            bWriter.newLine();
        }
        bWriter.close();
    }

}


LineNumberReader:

import java.io.FileReader;
import java.io.IOException;
import java.io.LineNumberReader;

public class Demo6_LineNumberReader {

    public static void main(String[] args) throws IOException {
        LineNumberReader lReader = new LineNumberReader(new FileReader("a.txt"));
        String line;
        lReader.setLineNumber(10);  //默认是0
        while((line=lReader.readLine())!=null) {
            System.out.println(lReader.getLineNumber()+":"+line);
        }
    }

}


装饰设计模式:

public class Demo7_Wrap {

    public static void main(String[] args) {
        // 装饰设计模式
        //耦合性不强,被装饰的类的变化与装饰类的变化无关
        BStudent student = new BStudent(new SmStudent());
        student.code();
//        数学
//        物理
//        化学
//        高数
//        线代
//        概率论

    }

}
interface Coder{
    public abstract void code();
}

class SmStudent implements Coder{

    @Override
    public void code() {
        System.out.println("数学");
        System.out.println("物理");
        System.out.println("化学");
        
    }
    
}
class BStudent implements Coder{
    private SmStudent student; //获取到被包装的类的引用
    public BStudent(SmStudent student){ //通过构造函数创建对象的时候,传入被包装的对象
        this.student = student;
    }
    @Override
    public void code() { //对其原有功能进行升级
        student.code();
        System.out.println("高数");
        System.out.println("线代");
        System.out.println("概率论");
    }
}



使用指定的码表读写字符:
* FileReader是使用默认码表读取文件, 如果需要使用指定码表读取, 那么可以使用
InputStreamReader(字节流,编码表)
* FileWriter是使用默认码表写出文件, 如果需要使用指定码表写出, 那么可以使用
OutputStreamWriter(字节流,编码表)
*
        BufferedReader br =                                
    //高效的用指定的编码表读
                new BufferedReader(new InputStreamReader(new FileInputStream("UTF-8.txt"), "UTF-8"));
        BufferedWriter bw =                                
    //高效的用指定的编码表写
              new BufferedWriter(new OutputStreamWriter(new FileOutputStream("GBK.txt"), "GBK"));
        int ch;
        while((ch = br.read()) != -1) {
            bw.write(ch);
        }
        
        br.close();
        bw.close();

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.TreeMap;

public class Test1 {

    public static void main(String[] args) throws IOException {
        //获取一个文本上每个字符出现的次数,将结果写在times.txt上
        BufferedReader bReader = new BufferedReader(new FileReader("a.txt"));
        TreeMap<Character, Integer> treeMap = new TreeMap<>();//创建双列集合对象TreeMap
        int line;
        while((line=bReader.read())!=-1) {
            char c = (char)line;
            //将读到的字符存储在双列集合中,存储的时候要做判断,如果不包含这个键,

就将键和1存储,如果包含这个键,就将该键和值加1存储
            treeMap.put(c, !treeMap.containsKey(c) ? 1 : treeMap.get(c)+1);
        }
        bReader.close();
        
        BufferedWriter bWriter = new BufferedWriter(new FileWriter("times.txt"));
        
        //遍历集合将集合中的内容写到times.txt中
        for (Character c : treeMap.keySet()) {
            switch (c) {
            case '	':
                bWriter.write("\t"+"="+treeMap.get(c));
                break;
            case '
':
                bWriter.write("\n"+"="+treeMap.get(c));
                break;
            case '
':
                bWriter.write("\r"+"="+treeMap.get(c));
                break;
            default:
                bWriter.write(c+"="+treeMap.get(c));
                break;
            }
            bWriter.newLine();
        }
        bWriter.close();
    }

}


递归练习:

public class Demo5_Digui {

    public static void main(String[] args) {
        //5的阶乘
        //数太大,会造成栈内存溢出
        System.out.println(fun(5)); //120

    }
    public static int fun(int num) {
        if (num==1) {
            return 1;
        }else {
            return num*fun(num-1);
        }
    }
}

递归注意事项:
* 调用次数太多,会造成栈内存溢出
* 构造方法不能递归
* 递归可以没有返回值
import java.io.File;
import java.util.Scanner;

public class Test2 {

    public static void main(String[] args) {
        //需求:从键盘输入接收一个文件夹路径,打印出该文件夹下所有的.java文件名
        File dir = getDir();
        printJavaFile(dir);

    }
    public static File getDir() {
        Scanner scanner = new Scanner(System.in);
        System.out.println("输入文件夹路径");
        while(true) {
            String line = scanner.nextLine();
            File dir = new File(line);
            if (!dir.exists()) {
                System.out.println("路径不存在,重新输入");
            }else if (dir.isFile()) {
                System.out.println("不是文件夹,重写输入");
            } else {
                return dir;
            }
        }
    }
    
    public static void printJavaFile(File dir) {
        File[] subFiles = dir.listFiles();
        for (File subFile : subFiles) {
            if (subFile.isFile() && subFile.getName().endsWith(".java")) {
                System.out.println(subFile);
            }else if (subFile.isDirectory()) {
                printJavaFile(subFile);
            }
        }
    }

}


序列流SequenceInputStream:

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 Demo1_SequenceInputStream {
    /*什么是序列流?
    序列流可以把多个字节输入流整合成一个, 从序列流中读取数据时, 将从被整合的第一个流开

始读, 读完一个之后继续读第二个, 以此类推.*/
    public static void main(String[] args) throws IOException {
    /*    //整合两个: SequenceInputStream(InputStream, InputStream)
        SequenceInputStream sis = new SequenceInputStream(new FileInputStream

("a.txt"), new FileInputStream("b.txt"));
        
        FileOutputStream fot = new FileOutputStream("c.txt");
        int line;
        while((line=sis.read())!=-1) {
            fot.write(line);
        }
        sis.close();
        fot.close();*/
        
//        整合多个: SequenceInputStream(Enumeration)
        Vector<FileInputStream> vector = new Vector<>();
        vector.add(new FileInputStream("a.txt"));
        vector.add(new FileInputStream("b.txt"));
        vector.add(new FileInputStream("c.txt"));
        
        Enumeration<FileInputStream> enumeration = vector.elements();
        SequenceInputStream sInputStream = new SequenceInputStream(enumeration);
        FileOutputStream fos = new FileOutputStream("d.txt");
        int line;
        while((line=sInputStream.read())!=-1) {
            fos.write(line);
        }
        sInputStream.close();
        fos.close();
    }

}


内存输出流ByteArrayOutputStream :

import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.IOException;

public class Demo2_ByteArrayOutputStream {

    public static void main(String[] args) throws IOException {
        //内存输出流
        //该输出流可以向内存中写数据, 把内存当作一个缓冲区, 写出之后可以一次性获取

出所有数据
        FileInputStream fis = new FileInputStream("d.txt");
        ByteArrayOutputStream bStream = new ByteArrayOutputStream();//在内存中创建

了可增长的内存数组
        
        int b;
        while((b=fis.read())!=-1) {  //将读到的数据逐个写到内存
            bStream.write(b);
        }
//        byte[] arr = bStream.toByteArray(); //将缓冲区的数据全部获取出来,并赋值给

字节数组
//        System.out.println(new String(arr));
        
        System.out.println(bStream.toString());//toString()可不写,默认调用
        
        fis.close();
        
    }

}


练习:

import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.IOException;

public class test1 {

    public static void main(String[] args) throws IOException {
        //定义一个文件输入流,调用read(byte[] b)方法,
        //将a.txt文件中的内容打印出来(byte数组大小限制为5)
        FileInputStream fis = new FileInputStream("a.txt");
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        
        byte[] bytes = new byte[5];
        int len;
        while((len=fis.read(bytes))!=-1) {
            baos.write(bytes, 0, len);
        }
        System.out.println(baos.toString());
        fis.close();
    }

}


随机访问流RandomAccessFile:

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

public class Demo3_RandomAccessFile {

    public static void main(String[] args) throws IOException {
        //随机访问流
        /*RandomAccessFile类不属于流,是Object类的子类。但它融合了InputStream和

OutputStream的功能。
        支持对随机访问文件的读取和写入。*/
        RandomAccessFile raf = new RandomAccessFile("d.txt", "rw");
        /*int i;
        while((i=raf.read())!=-1) {
            System.out.println(i);
        }*/
        raf.seek(4);  //设置指针的位置
        raf.write(97);
        
        raf.close();
    }

}



对象操作流:

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;

import com.fly.bean.Person;

public class Demo4_ObjectStream {
    /*    要写出的对象必须实现Serializable接口才能被序列化
    不用必须加id号*/
    public static void main(String[] args) throws IOException, ClassNotFoundException {
    /*    //对象操作流
        //将一个对象写出, 或者读取一个对象到程序中
        //将对象写出,序列化
        Person p1 = new Person("李四", 19);
        Person p2 = new Person("王五", 20);
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream

("e.txt"));
        oos.writeObject(p1);
        oos.writeObject(p2);
        oos.close();
        
        //读取对象,反序列化
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream

("e.txt"));
        Person p1 = (Person)ois.readObject();
        Person p2 = (Person)ois.readObject();
        System.out.println(p1);
        System.out.println(p2);
        ois.close();*/
        
/*        Person p1 = new Person("李四", 19);
        Person p2 = new Person("王五", 20);
        Person p3 = new Person("赵五", 21);
        ArrayList<Person> arrayList = new ArrayList<>();
        arrayList.add(p1);
        arrayList.add(p2);
        arrayList.add(p3);
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream

("e.txt"));
        oos.writeObject(arrayList);
        oos.close();*/
        
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream

("e.txt"));
        @SuppressWarnings("unchecked")
        ArrayList<Person> arrayList = (ArrayList<Person>) ois.readObject();
        
        for (Person person : arrayList) {
            System.out.println(person);
        }
        ois.close();
    }

}



数据输入输出流:

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class Demo5_Data {

    public static void main(String[] args) throws IOException {
        /*数据输入输出流:
          DataInputStream, DataOutputStream可以按照基本数据类型大小读写数据
           例如按Long大小写出一个数字, 写出时该数据占8字节. 读取的时候也可以按照

Long类型读取, 一次读取8个字节.
*/
        /*DataOutputStream dos = new DataOutputStream(new FileOutputStream

("f.txt"));
        dos.writeInt(997);
        dos.writeInt(998);
        dos.writeInt(999);
        
        dos.close();*/
        
        DataInputStream dis = new DataInputStream(new FileInputStream("f.txt"));
        System.out.println(dis.readInt());
        System.out.println(dis.readInt());
        System.out.println(dis.readInt());
//        System.out.println(dis.readInt());  // EOFException
        dis.close();
    }

}



打印流:

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

import com.fly.bean.Person;

public class Demo6_Print {

    public static void main(String[] args) throws IOException {
        // 打印流
        //PrintStream和PrintWriter分别是打印的字节流和字符流
        //只操作数据目的的
        /*PrintStream printStream = System.out;
        printStream.println(97);//97 //底层通过Integer.toString()将97转换成字符串并

打印
        printStream.write(97);//a   //查找码表,找到对应的a并打印
        Person person = new Person("xx",11);
        printStream.println(person);
        Person person2 = null;
        printStream.println(person2);//Person [name=xx, age=11] //默认调用person的

toString方法
        printStream.close();//null //打印引用数据类型,如果是null,就打印null,如果不

是null就打印对象的toString方法
    */
        PrintWriter printWriter = new PrintWriter(new FileOutputStream

("f.txt"),true);
        printWriter.println(97); //97 //自动刷出功能只针对的是println方法
        printWriter.write(97); //a
        printWriter.close();
        
    }

}


标准输入输出流:
    System.in是InputStream, 标准输入流, 默认可以从键盘输入读取字节数据
    System.out是PrintStream, 标准输出流, 默认可以向Console中输出字符和字节数据
修改标准输入输出流:
    修改输入流: System.setIn(InputStream)
    修改输出流: System.setOut(PrintStream)

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;

public class Demo06_SystemInOut {

    /**
     * @param args
     * @throws IOException
     */
    public static void main(String[] args) throws IOException {
        //demo1();
        System.setIn(new FileInputStream("a.txt"));            //改变标准

输入流
        System.setOut(new PrintStream("b.txt"));            //改变标注

输出流
        
        InputStream is = System.in;                            

//获取标准的键盘输入流,默认指向键盘,改变后指向文件
        PrintStream ps = System.out;                        //

获取标准输出流,默认指向的是控制台,改变后就指向文件
        
        int b;
        while((b = is.read()) != -1) {
            ps.write(b);
        }
        //System.out.println();                                

//也是一个输出流,不用关,因为没有和硬盘上的文件产生关联的管道
        is.close();
        ps.close();
        
    }

    public static void demo1() throws IOException {
        InputStream is = System.in;
        int x = is.read();
        System.out.println(x);
        
        is.close();
        
        InputStream is2 = System.in; //只存在一个,已经关闭了
        int y = is2.read();
        System.out.println(y);
    }

}



两种方式实现键盘录入:
BufferedReader的readLine方法。
     BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
Scanner


Properties类:

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.util.Enumeration;
import java.util.Properties;

public class Demo7_Properties {

    /*Properties:
    Properties 类表示了一个持久的属性集。
    Properties 可保存在流中或从流中加载。
    属性列表中每个键及其对应值都是一个字符串。 */

/*    Properties的特殊功能:
    public Object setProperty(String key,String value)
    public String getProperty(String key)
    public Enumeration<String> stringPropertyNames()*/
    
    public static void main(String[] args) throws IOException {
        // Properties作为Map集合的使用
        /*Properties properties = new Properties();
        properties.put("abc", 123);
        System.out.println(properties);//{abc=123}
*/
        
    /*    Properties properties = new Properties();
        properties.setProperty("name", "张三");
        properties.setProperty("age", "19");
        
        Enumeration<String> en = (Enumeration<String>) properties.propertyNames();
        while (en.hasMoreElements()) {
            String key = en.nextElement();
            String value = properties.getProperty(key);
            System.out.println(key+"="+value);
        }*/
        
        //Properties的load()和store()功能
        Properties properties = new Properties();
        properties.load(new FileInputStream("config.properties"));
        
        System.out.println(properties);
        
        properties.setProperty("qq", "20000");
        properties.store(new FileOutputStream("config.properties"), null); //参数二

是文件描述信息
        System.out.println(properties);
    }
    
}
原文地址:https://www.cnblogs.com/fly-book/p/9864961.html