第十六章 输入与输出

一.流的分类与理解

流

二.IO流的类库

类库

三.所有的流都需要close,输出流需要flush(flush:将输出流的数据强制写出,即清空输出流,防止数据丢失)

四.使用文件字节输入流读取文件

public class FileInputStreamTest01 {
    // 使用java.io.FileInputStream来读取一个文件。
    // 这个流是字节流,一次只能读取一个字节。(8个二进制位)
    public static void main(String[] args) {

        long begin = System.currentTimeMillis();

        FileInputStream fis = null;
        try {
            // 以下两种方式都是绝对路径。
            //FileInputStream fis = new FileInputStream("D:\\powernode\\java_manhua\\java_manhua\\data.txt");
            //FileInputStream fis = new FileInputStream("D:/powernode/java_manhua/java_manhua/data.txt");
            // 相对路径怎么写?
            // IDEA工具默认的当前路径是工程的根。
            fis = new FileInputStream("data.txt");
            int readByte = 0;
            while((readByte = fis.read()) != -1){
                //System.out.println(readByte);
            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fis != null) {
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        long end = System.currentTimeMillis();
        System.out.println("耗时"+(end - begin)+"毫秒");
    }
}

五.BufferedInputStream流提高读性能

public class BufferedInputStreamTest01 {

    // 使用BufferedInputStream提高读的性能
    // 内存和硬盘之间的交互次数越少,效率越高。
    // BufferedInputStream:是一个字节流。是一个输入流,负责读的。Buffered被翻译为缓存。
    // 这个流会在内存当中自备一个byte数组,这个byte数组就是一种缓存机制,然后一次性读取多个字节。
    // 放到缓存当中。减少内存和硬盘的交互。提高读的效率。
    /*
    public BufferedInputStream(InputStream in) {
        this(in, DEFAULT_BUFFER_SIZE);
    }
    这是BufferedInputStream的构造方法。
    BufferedInputStream流可以看做是包装流/处理流。
    参数InputStream流可以看做节点流。
    其实这里体现了一种设计模式:装饰模式。(GoF23种设计模式中的一种。)
     */
    public static void main(String[] args) {
        long begin = System.currentTimeMillis();
        BufferedInputStream bis = null;
        try {
            // 节点流
            FileInputStream fis = new FileInputStream("data.txt");
            // 包装流
            bis = new BufferedInputStream(fis);

            int readByte = 0;
            while((readByte = bis.read()) != -1){
                System.out.println(readByte);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 只需要关闭最外层的包装流。
            if (bis != null) {
                try {
                    bis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        long end = System.currentTimeMillis();
        System.out.println("耗时"+(end - begin)+"毫秒");
    }
}

六.DataInputStream的使用

public class DataInputOutputTest {

    /*
    1.DataOutputStream和DataInputStream是配合使用的。
    2.只有使用DataOutputStream流写的文件,DataInputStream才能读。
    3.DataOutputStream在写的时候,会连同类型一块写入到文件当中。
    DataInputStream在读的时候,也会连同类型一块读入到内存当中。
     */
    public static void main(String[] args) {
    //写入!!!
        /*DataOutputStream dos = null;
        try {
            // 创建DataOutputStream流,负责写。
            FileOutputStream fos = new FileOutputStream("d.txt");
            BufferedOutputStream bos = new BufferedOutputStream(fos);
            dos = new DataOutputStream(bos);

            // 开始写
            dos.writeBoolean(true);
            dos.writeDouble(3.14);

            // 记得刷新
            dos.flush();

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (dos != null) {
                try {
                    dos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }*/
		//读取!!!
        // 使用它的兄弟:DataInputStream来读取这个文件
        DataInputStream dis = null;
        try {
            FileInputStream fis = new FileInputStream("d.txt");
            BufferedInputStream bis = new BufferedInputStream(fis);
            dis = new DataInputStream(bis);
            // 开始读
            // 读的时候要注意:读的顺序和写的顺序必须一样。
            boolean b = dis.readBoolean();
            System.out.println(b);

            double v = dis.readDouble();
            System.out.println(v);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (dis != null) {
                try {
                    dis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

七.BufferedOutputStream流提高写性能

public class DataInputOutputTest {

    /*
    1.DataOutputStream和DataInputStream是配合使用的。
    2.只有使用DataOutputStream流写的文件,DataInputStream才能读。
    3.DataOutputStream在写的时候,会连同类型一块写入到文件当中。
    DataInputStream在读的时候,也会连同类型一块读入到内存当中。
     */
    public static void main(String[] args) {
        /*DataOutputStream dos = null;
        try {
            // 创建DataOutputStream流,负责写。
            FileOutputStream fos = new FileOutputStream("d.txt");
            BufferedOutputStream bos = new BufferedOutputStream(fos);
            dos = new DataOutputStream(bos);

            // 开始写
            dos.writeBoolean(true);
            dos.writeDouble(3.14);

            // 记得刷新
            dos.flush();

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (dos != null) {
                try {
                    dos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }*/

        // 使用它的兄弟:DataInputStream来读取这个文件
        DataInputStream dis = null;
        try {
            FileInputStream fis = new FileInputStream("d.txt");
            BufferedInputStream bis = new BufferedInputStream(fis);
            dis = new DataInputStream(bis);
            // 开始读
            // 读的时候要注意:读的顺序和写的顺序必须一样。
            boolean b = dis.readBoolean();
            System.out.println(b);

            double v = dis.readDouble();
            System.out.println(v);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (dis != null) {
                try {
                    dis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

八.PrintStream流的使用

public class PrintStreamTest {
    // PrintStream流的使用,PrintStream流是自动刷新
    // PrintStream流是一个标准输出流。
    public static void main(String[] args) throws Exception{

        System.out.println("Hello World!");

        // 将以上代码拆分为下面两行,可以看到System.out居然返回了一个PrintStream流对象。
        // 标准的输出流对象默认是向控制台打印信息。
        PrintStream ps = System.out;
        ps.println("Hello World!");

        // 可以自定义标准输出流的输出方向。(程序员是可以干预的。)
        // 创建PrintStream对象
        FileOutputStream fos = new FileOutputStream("logfile.txt", true);
        BufferedOutputStream bos = new BufferedOutputStream(fos);
        PrintStream pout = new PrintStream(bos);
        //PrintStream pout = new PrintStream(fos);

        // 改变标准输出流的方向。
        System.setOut(pout);

        System.out.println("Hello World!");
        System.out.println("Hello World!");
        System.out.println("Hello World!");
        System.out.println("Hello World!");
        System.out.println("Hello World!");

        // 如果使用的是缓冲流的话,这个刷新就需要自己刷新了。
        pout.flush();
    }
}

九.InputStreamReader解决读的乱码问题

public class InputStreamReaderTest {
    public static void main(String[] args) throws Exception{
        // 读取D:/a.txt文件,这个文件目前的字符集是GBK的方式。
        FileInputStream fis = new FileInputStream("D:/a.txt");
        // InputStreamReader他是一个字符流。
        // InputStreamReader他也是一个转换流:将字节流转换成字符流。
        // java程序是基于Unicode方式,UTF-8的方式读取这个文件的。有问题吗?
        // 解决乱码问题两种方案:
        // 第一种:将a.txt的字符集修改为UTF-8
        // 第二种:创建InputStreamReader流的时候,指定读取的字符集。
        InputStreamReader reader = new InputStreamReader(fis, "GBK");
        // 开始读
        System.out.println((char)reader.read());
        // 关闭流
        reader.close();
    }
}

十.BufferedReader的使用

public class BufferedReaderTest {
    // BufferedReader类的使用
    // 带有缓冲区的字符流。
    public static void main(String[] args) throws Exception{
        BufferedReader br = new BufferedReader(new FileReader("logfile.txt"));
        String s = null;
        while((s = br.readLine()) != null) {
            System.out.println(s);
        }

        br.close();
    }
}

十一.OutputStreamWriter解决写的乱码问题

public class OutputStreamWriterTest {
    //采用指定字符集的方式写文件
    public static void main(String[] args) throws Exception{
        // a.txt文件是GBK的字符集。
        FileOutputStream fos = new FileOutputStream("D:/a.txt", true);
        // 创建转换流
        OutputStreamWriter osw = new OutputStreamWriter(fos, "GBK");

        // 写
        osw.write("大家好,欢迎大家学习漫画Java编程!");

        // 刷新
        osw.flush();
        // 关闭
        osw.close();
    }
}

十二.实现文件拷贝

public class CopyFile {
    public static void main(String[] args) {
        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;
        try {
            // 拷贝文件
            // 为了拷贝任何类型的文件,我们这里采用字节流进行拷贝。
            // 一边读一遍写。(FileInputStream FileOutputStream)
            // 创建输入流和输出流
            FileInputStream fis = new FileInputStream("D:/1.jpg");
            bis = new BufferedInputStream(fis);
            FileOutputStream fos = new FileOutputStream("D:/2.jpg");
            bos = new BufferedOutputStream(fos);

            // 一遍读一遍写
            int readByte = 0;
            while((readByte = bis.read()) != -1) {
                bos.write(readByte);
            }

            bos.flush();
        } catch (IOException e){
            e.printStackTrace();
        } finally {
            if (bis != null) {
                try {
                    bis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (bos != null) {
                try {
                    bos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

十三.File类的使用

public class FileTest {
    // File类的使用
    // File不是IO流,通过它不能完成读和写。
    // File是文件系统中 文件路径的 抽象表示。
    // D:\java_manhua 虽然是一个目录,它也是一个File
    // D:\java_manhua\data.txt 是一个文件,它也是一个File
    // File实际上是一个路径的抽象表示形式。File既可以是一个目录,也可以是一个文件。
    public static void main(String[] args) throws Exception{
        /*
            boolean exists():测试该 File 对象所代表的文件或者目录是否存在。
            boolean mkdir():在文件系统中创建由该 File 对象表示的目录。
            boolean createNewFile():如果该 File 对象代表文件,并且该文件在文件系统中不存在,就在文件系统中创建这个文件,内容为空。
            boolean isDirectory():测试该 File 对象是否代表一个目录。
            boolean isFile():测试该 File 对象是否代表一个文件。
            String getPath():获取该 File 对象所代表的文件或者目录的路径。
            String getName():获取该 File 对象所代表的文件或者目录的名字。
            boolean delete():删除该 File 对象所代表的文件或者目录。如果 File 对象代表目录,并且目录下包含子目录或文件,则不允许删除 File 对象代表的目录。
            String getParent():获取该 File 对象所代表的文件或者目录的根路径。如果没有根路径,就返回 null。
            File[] listFiles():如果该 File 对象代表目录,则返回该目录下所有文件和目录的 File对象。
         */
        /*// 创建File对象
        File f1 = new File("D:/a");
        // 如果d:/a目录不存在,则新建目录
        if(!f1.exists()){
            // 以目录的形式新建
            //f1.mkdir();
            // 以文件的形式新建
            f1.createNewFile();
        }*/

        /*File f1 = new File("D:/a/b/c");
        if(!f1.exists()){
            f1.mkdirs();
        }*/

       /* File f1 = new File("d:/a/b/c");
        System.out.println(f1.isDirectory()); // true
        System.out.println(f1.isFile()); // false

        System.out.println(f1.getPath());
        System.out.println(f1.getName());

        System.out.println(f1.getParent());
        System.out.println(f1.getParentFile().getPath());

        f1.delete();*/

        // 获取当前目录下的所有子文件
        File f1 = new File("D:\\java_manhua");
        File[] files = f1.listFiles();
        for (File file : files) {
            System.out.println(file.getAbsolutePath());
        }
    }
}

十四.使用nio下的子包file中的工具类

public class FileTool {
    public void copyFile(String fromDir, String toDir,
                         String file) throws IOException {
        Path pathFrom = Paths.get(fromDir, new String[]{file});
        Path pathTo = Paths.get(toDir, new String[]{file});
        // 复制文件,如果目标文件已经存在就将其覆盖
        Files.copy(pathFrom, pathTo,
                StandardCopyOption.REPLACE_EXISTING);
    }

    public void moveFile(String fromDir, String toDir,
                         String file) throws IOException {
        Path pathFrom = Paths.get(fromDir, new String[]{file});
        Path pathTo = Paths.get(toDir, new String[]{file});
        // 移动文件,如果目标文件已经存在就将其覆盖
        Files.move(pathFrom, pathTo,
                StandardCopyOption.REPLACE_EXISTING);
    }

    public void list(String dir) throws IOException {
        Path path = Paths.get(dir);
        // 获得 path 目录下的所有文件和子目录,不包含子目录下的嵌套内容
        DirectoryStream<Path> paths =
                Files.newDirectoryStream(path);
        for (Path p : paths)
            System.out.println(p.getFileName());
    }

    public static void main(String[] args) throws IOException {
        FileTool tool = new FileTool();
        // 把 D:\mydir 目录下的 data.txt 文件复制到 D:\tmp 目录下
        //tool.copyFile("D:\\mydir", "D:\\tmp", "data.txt");

        // 把 D:\mydir 目录下的 data.txt 文件移动到 D:\tmp 目录下
        //tool.moveFile("D:\\mydir", "D:\\tmp", "data.txt");

        // 遍历 D:\mydir 目录下的内容
        tool.list("D:\\java_manhua");
    }
}

十五.遍历目录树

public class Test {
    // 遍历目录树
    public static void main(String[] args) {
        String path = "D:\\java_manhua";
        File f = new File(path);
        walkFileTree(f);
    }

    private static void walkFileTree(File f) {
        // 递归的结束条件
        if (f.isFile()) {
            return;
        }

        File[] files = f.listFiles();
        for (File file : files){
            System.out.println(file.getAbsolutePath());
            walkFileTree(file);
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

是柒浔啊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值