InputStream和OutputStream

文章目录

    • FileInputStream 构造方法
    • InputStream 常用方法
    • OutputStream 概述
    • OutputStream 常用方法
    • PrintWriter
    • 小程序练习

使用字节流进行读/写操作时,是以字节为单位的;

InputStream 只是一个抽象类,在实例化时,需要使用具体的实现类,而InputStream 的实现类有很多,可以认为不同的输入设备都对应着一个InputStream 类,而针对于文件读写时,主要使用 FileInputStream

FileInputStream 构造方法

构造方法 说明
FileInputStream(File file) 使用 File 对象构造输入流
FileInputStream(String name) 使用文件路径构造输入流

InputStream 常用方法

返回值 方法 说明
int read() 读取一个字节的数据,返回-1代表已经读完
int read(byte[] b) 最多读取b.length长度字节的数据到b中,返回实际读到的数量,-1表示读完
int read(byte[] b, int off, int len) 最多读取off-len长度字节的数据到数组中,从off位置开始放数据
void close() 关闭字节流

代码演示:

第一种读取方式:

    public static void main(String[] args) {
        try(InputStream is = new FileInputStream("d:/新建文件夹/text.txt")) {
            while(true) {
                byte[] b = new byte[1024];
                int n = is.read(b);//返回读到的字节个数
                System.out.println(n);
                if(n == -1) {
                    //表示数据已经读完了
                    break;
                }
                for(int i = 0; i < n; i++) {
                    System.out.printf("%x\n",b[i]);//用十六进制显示
                }
            }

        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

InputStream和OutputStream_第1张图片

第二种读取方式:使用Scanner进行读取

Scanner(InputStream is, String charset) 使用charset字符集对流对象进行读取
    public static void main(String[] args) {
        try(InputStream is = new FileInputStream("d:/新建文件夹/text.txt");
            Scanner scanner = new Scanner(is, "UTF-8")) {
            //使用Scanner包装一下流对象,将读的内容转换为字符
            while(scanner.hasNext()) {
                String s = scanner.next();
                System.out.println(s);
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

InputStream和OutputStream_第2张图片

OutputStream 概述

与InputStream一样,OutputStream也是一个抽象类,需要具体类进行实现,例如:FileOutputStream ,构造方法的参数与InpuStream也是一样的;

OutputStream 常用方法

返回值 方法 说明
void write() 写入一个字节的数据
void write(byte[] b) 将b这个数组中的数据全都写入文件中
void write(byte[] b, int off, int len) 将b这个字节数组中,从off这个位置开始的数据写入文件中,一直写len个长度
void close() 关闭字节流
void flush() 下面讲解

flush作用:

举一个例子,平时嗑瓜子时,难道我们嗑一个瓜子就跑出去扔一个瓜子皮吗?并不是的,而是嗑了许多瓜子之后,瓜子皮一块扔,这样就很省力气,OutputStream 也就是这样的,因为写向硬盘中写入数据时是很慢的,所以,会将写入的数据先存放在缓冲中,等缓冲区满了,再写入到硬盘中,但是这样就会有一个缺陷就是,如果还没来得及写入硬盘中时,进程就结束了,那么数据就遗留到了缓冲区中,所以为了防止这种情况,就可以在合适的位置使用 flush() 来刷新缓冲区,这样才真正的将数据写入到了硬盘中

示例一:

import java.io.*;
	public static void main(String[] args) {
        //参数中指定一个true表示,写入数据时,不会将文件中原有的数据覆盖掉
        try(OutputStream os = new FileOutputStream("d:/新建文件夹/text.txt", true)) {
            os.write('a');
            os.write('b');
            os.write('c');
            os.flush();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

示例二:

import java.io.*;
	public static void main(String[] args) {
        //参数中指定一个true表示,写入数据时,不会将文件中原有的数据覆盖掉
        try(OutputStream os = new FileOutputStream("d:/新建文件夹/text.txt", true)) {
            byte[] b = new byte[]{(byte)'Q',(byte)'E',(byte)'R',(byte)'T'};
            os.write(b);//将数组中的数据全都写入到文件中
            os.flush();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

示例三:

import java.io.*; 
	public static void main(String[] args) {
        //参数中指定一个true表示,写入数据时,不会将文件中原有的数据覆盖掉
        try(OutputStream os = new FileOutputStream("d:/新建文件夹/text.txt", true)) {
            byte[] b = new byte[]{(byte)'Q',(byte)'E',(byte)'R',(byte)'T'};
            os.write(b, 0, 3);//将数组中的数据从0位置开始写入到文件中,写入3个字节的数据
            os.flush();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

示例四:

import java.io.*; 
	public static void main(String[] args) {
        //参数中指定一个true表示,写入数据时,不会将文件中原有的数据覆盖掉
        try(OutputStream os = new FileOutputStream("d:/新建文件夹/text.txt", true)) {
            String s = "你好中国";
            byte[] b = s.getBytes();
            //s.getBytes("UTF-8");指定一个字符集
            os.write(b);
            os.flush();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

PrintWriter

在上述的流对象中,写入数据时,都必须先转化成字节然后再写入,这对于这一点,可以使用PrintWriter 这个类对输出流进行包装,这样就不用我们自己手动的转化了;

PrintWriter 类中,也提供 Print()、printf()、println() 这样的方法进行写入

演示:

public static void main(String[] args) {
        try(OutputStream os = new FileOutputStream("d:/新建文件夹/text.txt")) {
            try(OutputStreamWriter osw = new OutputStreamWriter(os, "UTF-8");
                //也可以省略上一行直接写PrintWriter pw = new PrintWriter(os),只不过这里没有指定字符集
                PrintWriter pw = new PrintWriter(osw)) {//告诉它我们使用的字符集时UTF-8

                pw.println("我是第一行");//println写入时,会自动写入一个字符串
                pw.print("我是第二行\n");
                pw.printf("%s\n", "我是第三行");
                pw.flush();
            }

        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

InputStream和OutputStream_第3张图片

小程序练习

示例1:

扫描指定路径,并找到名称中包含指定字符的所有普通文件,并且后续询问用户是否要删除该文件

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        //1.输入文件路径
        Scanner in = new Scanner(System.in);
        while(true) {
            System.out.println("请输入要扫描的路径");
            String path = in.nextLine();
            //2.判断路径是否正确
            File path_file = new File(path);
            while(true) {
                if(!path_file.exists()) {
                    System.out.println("您输入的路径不存在,请重新输入");
                }else if(!path_file.isDirectory()) {
                    System.out.println("您输入的路径不是一个目录,请重新输入");
                }else{
                    break;
                }
                path = in.nextLine();
                path_file = new File(path);
            }
            //3.递归扫描目录,将目标文件加入到集合中
            System.out.println("请输入指定字符");
            String aim_char = in.nextLine();
            List<File> result = new ArrayList<>();
            search_comment(path_file, aim_char, result);
            //4.遍历这个集合,判断是否要删除该文件
            for(File f : result) {
                //打印该文件名称
                System.out.println("是否要删除该文件"+f.getName()+"(Yes/No):");
                while(true) {
                    String input = in.nextLine().toLowerCase();
                    if(input.equals("yes")) {
                        //5.删除操作
                        f.delete();
                        System.out.println("删除成功");
                        break;
                    }else if(input.equals("no")){
                        System.out.println("取消删除");
                        break;
                    }else {
                        System.out.println("输入有误,请重新输入");
                    }
                }
            }
        }

    }
    private static void search_comment(File path, String aim, List<File> result) {
        //将path这个目录中的所有文件全部拿出来进行遍历
        File[] all_file = path.listFiles();
        if(all_file == null || all_file.length == 0) {
            return;
        }
        for(File f : all_file) {
            if(f.isDirectory()) {
                //如果f是一个目录,那么就继续递归这个目录
                search_comment(f, aim, result);
            }else {
                //判断该文件是否是目标文件
                if(f.getName().contains(aim)) {
                    //该文件是目标文件,加入到result中
                    result.add(f);
                }
            }
        }
    }
}

示例2:

进行 普通文件的复制

import java.io.*;
import java.util.Scanner;

public class Main {

    public static void main(String[] args) {
        //1.输入源文件路径
        Scanner scan = new Scanner(System.in);
        while (true) {
            System.out.println("请输入文件路径:>");
            String srcPath = scan.nextLine();
            //2.构建file对象
            File srcFile = new File(srcPath);
            //3.检查指定的源文件
            while(true) {
                if(!srcFile.exists()) {
                    //判断指定的文件是否存在
                    System.out.println("你输入的路径不存在,请重新输入!!!");
                }else if(!srcFile.isFile()) {
                    //如果是目录,则重新输入
                    System.out.println("您输入的路径不是一个普通文件,请重新输入!!!");
                }else {
                    break;
                }
                srcPath = scan.nextLine();
                srcFile = new File(srcPath);
            }
            //4.输入目标路径
            System.out.println("请输入目标文件路径:>");
            String destPath = scan.nextLine();
            File destFile = new File(destPath);
            //判断要复制的文件在该路径下是否已经存在
            while(true) {
                if(!destFile.exists()) {
                    //如果文件不存在,则创建一个文件
                    try {
                        destFile.createNewFile();
                        break;
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                }else if(destFile.isDirectory()) {
                    System.out.println("您输入的路径是一个目录,请重新输入");
                }else if(destFile.isFile()){
                    //表示目标文件已经存在,是否进行覆盖
                    System.out.println("目标文件已经存在,是否进行覆盖(Yes/No)");
                    String input = scan.nextLine().toLowerCase();
                    if(!input.equals("no")) {
                        break;
                    }else {
                        System.out.println("停止复制");
                        return;
                    }
                }else {
                    break;
                }
                destPath = scan.nextLine();
                destFile = new File(destPath);
            }
            //复制文件
            try(InputStream is = new FileInputStream(srcFile);
                OutputStream os = new FileOutputStream(destFile)) {
                //定义一个数组,用来存储读出的内容
                byte[] arr = new byte[1024];
                //定义一个标记,用来记录是否读到最后的位置
                int len;
                while(true) {
                    //定义循环是为了防止内容不能一次读完
                    len = is.read(arr);
                    if(len == -1) {
                        break;
                    }
                    os.write(arr, 0, len);
                }
                os.flush();

            } catch (IOException e) {
                throw new RuntimeException(e);
            }
            System.out.println("复制完毕!!!");
        }
    }
}

你可能感兴趣的:(java,笔记,经验分享)