File、IO流

File类

概念

File类,它就用来表示当前系统下的文件(也可以是文件夹),通过File类提供的方法可以获取文件大小、判断文件是否存在、创建文件、创建文件夹等。

注意:

File对象只能对文件进行操作,不能操作文件中的内容。

File对象的创建

定义格式:

File f1 = new File("C:\\JavaSE\\Hello.java"); //使用绝对路径指向文件
File f2 = new File("JavaSE/Hello.java");      //使用相对路径指向文件
File f3 = new File("C:\\JavaSE");             //使用绝对路径指向目录
File f4 = new File("JavaSE/code");            //使用相对路径指向目录
File判断和获取方法

方法代码:

public static void main(String[] args) {
    //创建一个File对象,指代某个文件,使用绝对路径
    File f1 = new File("C:\\JavaSE\\HelloWorld.java");
    //判断文件是否存在,如果存在则返回true,否则返回false
    boolean exists = f1.exists();

    //判断当前文件对象指代的是文件
    boolean isFile = f1.isFile();

    //判断当前文件对象指代的是目录
    boolean isDirectory = f1.isDirectory();

    //获取文件名称
    String fileName = f1.getName();

    //获取文件大小
    long length = f1.length();

    //获取文件的最后修改时间(时间戳)
    long lastModified = f1.lastModified();

    //获取文件路径
    String path = f1.getParent();

    //获取文件的绝对路径
    String absolutePath = f1.getAbsolutePath();
}
File创建和删除方法

方法代码:

public static void main(String[] args) throws Exception {
    //创建一个文件对象
    File file = new File("E:\\hello.txt");//当前文件还不存在
    System.out.println(file.exists());    //false
    //在磁盘中创建这个文件,如果文件已经存在则不会再创建,此时返回false
    boolean newFile = file.createNewFile();
    System.out.println(file.exists());//true

    //创建一个File对象指代磁盘中的目录
    File dir = new File("E:\\hello");
    //在磁盘中创建这个目录,如果创建成功则返回true,否则返回false
    boolean mkdir = dir.mkdir();
    System.out.println(mkdir);

    //一次创建对级目录
    File dirs = new File("E:\\hello\\a\\b\\c");
    //目录不存在时才创建,如果创建成功则返回true,否则返回false
    boolean mkdirs = dirs.mkdirs();
    System.out.println(mkdirs);

    //-----可以删除指定文件,也可以删除一个空目录-----
    if(file.exists()){   //文件存在时再执行删除操作
        //删除一个文件,如果删除成功则返回true,否则返回false
        boolean delete = file.delete();
        System.out.println(delete);
    }

    //删除一个空目录,如果删除成功则返回true,否则返回false
    boolean delete = dirs.delete();
    System.out.println(delete);
}
File遍历文件夹方法

方法代码:

public static void main(String[] args) {
    //创建一个File对象,指代某个目录
    File dir = new File("E:\\code");

    //获取目录中的一级文件名称(包含了目录和文件)
    String[] names = dir.list();
    for (String name : names) {
        System.out.println(name);
    }

    //获取目录中的一级文件对象(包含了目录和文件)
    File[] files = dir.listFiles();
    for (File file : files) {
        System.out.println("文件名:" + file.getName() + " 文件大小:" + file.length());
    }
}

递归

概念

递归是一种算法,从形式上来说,方法调用自己的形式称之为递归。

递归的形式:直接递归、间接递归

示例代码:

public static void main(String[] args) {
    method1();
}

public static void method1(){
    //自己调用自己---直接递归
    method1();

    //调用其他方法,其他方法有调用自己---间接递归
    method2();
}

public static void method2(){
    method1();
}
递归案例–文件搜索

案例需求:在D:\\下搜索QQ.exe这个文件。

示例代码:

public static void main(String[] args) {
    boolean search = search(new File("D:\\"), "QQ.exe");
    if (search){
        System.out.println("已找到");
    }else {
        System.out.println("查找失败");
    }
}

public static boolean search(File dir, String name){
    if (!dir.exists() || dir.isFile()){
        return false;
    }

    File[] files = dir.listFiles();
    if (files != null){
        for (File file : files) {
            if (file.isFile()){
                if (file.getName().equals(name)) {

                    return true;
                }
            }else {
                if (search(file,name)){
                    return true;
                }
            }
        }
    }
    return false;
}

拓展—字符集

小结
ASCII字符集:《美国信息交换标准代码》,包含英文字母、数字、标点符号、控制字符
 
特点:1个字符占1个字节
 
GBK字符集:中国人自己的字符集,兼容ASCII字符集,还包含2万多个汉字
 
特点:1个字母占用1个字节;1个汉字占用2个字节
 
Unicode字符集:包含世界上所有国家的文字,有三种编码方案,最常用的是UTF-8
 
UTF-8编码方案:英文字母、数字占1个字节兼容(ASCII编码)、汉字字符占3个字节

IO流

作用

对文件或者网络中的数据进行读写操作。

  • 把数据从磁盘、网络中读取到程序中来,用到的是输入流

  • 把程序中的数据写入磁盘、网络中,用到的是输出流

两大体系

1.字节流:字节流又分为字节输入流、字节输出流

2.字符流:字符流由分为字符输入流、字符输出流

FileInputStream–字节输入流

示例代码:

//读取单个字节
public static void main(String[] args) throws Exception {
    //创建输入流对象,通过此输入流对象可以读取文件中的字节
    FileInputStream is = new FileInputStream("E:\\hello\\helloworld.txt");
    //每次读取一个字节数据
    //int b1 = is.read();
    //int b2 = is.read();
    //int b3 = is.read();
    //int b4 = is.read();
    //int b5 = is.read();//文件读完了,返回-1
    //System.out.println(b5);

    int b;
    //每次读取一个字节数据,使用循环完成
    while ((b = is.read()) != -1) {
        System.out.println((char) b);
    }

    //IO流使用完成后需要关闭,否则占用系统资源
    is.close();
}
//读取多个字节
public static void main(String[] args) throws Exception {
    //创建输入流对象,通过此输入流对象可以读取文件中的字节
    FileInputStream is = new FileInputStream("E:\\hello\\helloworld.txt");

    //定义字节数组,用于存储读取到的字节数据
    byte[] b = new byte[3];
    int len;

    //每次读取多个字节到字节数组中,返回本次读取的字节数
    //int len = is.read(b);
    //len = is.read(b);
    //len = is.read(b);
    //len = is.read(b);

    //每次读取多个字节到字节数组中,返回本次读取的字节数---使用循环完成
    while ((len = is.read(b)) != -1) {
        //将byte数组中的字节解码为字符
        String s = new String(b, 0, len);
        System.out.println(s);
    }

    //IO流使用完成后需要关闭,否则占用系统资源
    is.close();
}
//读取全部字节
public static void main(String[] args) throws Exception {
    File file = new File("E:\\hello\\helloworld.txt");

    //创建输入流对象,通过此输入流对象可以读取文件中的字节
    FileInputStream is = new FileInputStream(file);

    //读取所有字节到一个字节数组中---方式一
    byte[] allBytes = new byte[(int) file.length()];//数组长度等于文件字节数
    is.read(allBytes);
    String data = new String(allBytes);
    System.out.println(data);

    //读取所有字节到一个字节数组中---方式二
    byte[] bytes = is.readAllBytes();
    String s = new String(bytes);
    System.out.println(s);

    //IO流使用完成后需要关闭,否则占用系统资源
    is.close();
}

除读取全部方法外,另外两种方法读取中文txt文件,都有可能出现中文乱码,但一次读取所有字节虽然可以解决乱码问题,但是文件不能过大,如果文件过大,可能导致内存溢出。因此不推荐使用字节流读取中文txt文件

FileOutputStream–字节输出流

示例代码:

public static void main(String[] args) throws Exception {
    //创建字节输出流对象,可以向指定文件写入字节数据
    FileOutputStream fos = new FileOutputStream("E:\\hello\\itcast.txt",true);

    //写一个字节
    fos.write(97);

    byte[] bytes = "a".getBytes();
    //写一个字节数组
    fos.write(bytes);

    byte[] bytes1 = "itcast".getBytes();
    //写字节数组的一部分
    fos.write(bytes1,0,2);

    //关闭管道
    fos.close();
}
案例—复制文件

示例代码:

public static void main(String[] args) throws Exception {
    //创建输入流,从原始文件中读取字节数据
    FileInputStream fis = new FileInputStream("D:\\1.jpg");

    //创建输出流,用于向指定文件写入字节数据
    FileOutputStream fos = new FileOutputStream("D:\\2.jpg");

    //准备一个字节数组,用于存放读取到的字节数据
    byte[] bytes = new byte[1024];

    //读取到的字节数
    int len;

    //循环读取文件中的字节数据,直到读取完
    while ((len = fis.read(bytes)) != -1){
        //使用输出流将读取到的字节数据写入到文件中
        fos.write(bytes,0,len);
    }

    //关闭资源
    fos.close();
    fis.close();
}
FileReader–字符输入流

示例代码:

public static void main(String[] args) throws Exception {
    //创建字符输入流对象,读取对应文件中的字符数据
    FileReader fileReader = new FileReader("D:\\钗头凤·红酥手txt");

    /*int b ;
    //每次读取一个字符,如果没有数据可读了返回-1
    while ((b = fileReader.read()) != -1){
        System.out.print((char) b);
    }*/

    //定义字符数组,用于存放通过字符输入流读取的字符数据
    char[] chars = new char[1024];
    int len;

    //每次读取多个字符数据放入字符数组中,len表示读取到的字符个数,如果没有数据可读返回-1
    while ((len = fileReader.read(chars)) != -1){
        String data = new String(chars, 0, len);
        System.out.println(data);
    }

    //关闭资源
    fileReader.close();
}
FileWriter–字符输出流

示例代码:

public static void main(String[] args) {
    try (
            //创建文件字符输出流,向指定的文件写入字符数据
            FileReader fr = new FileReader("D:\\钗头凤·红酥手.txt");
            FileWriter fw = new FileWriter("D:\\钗头凤·红酥手(副本).txt")
    ){
        //定义字符数组,用于存储读取的字符
        char[] chars = new char[1024];
        int len;
        // 使用len存储每次读取自己的个数,如果不等于负一则继续读取
        while ((len = fr.read(chars)) != -1){
            //将字符数组转成字符串写入,从0开始至读取到的字符个数结束,防止出现数组未读满默认填充的字符
            fw.write(new String(chars,0,len));
            System.out.println(chars);
        }
    } catch (Exception e) {
        e.getStackTrace();
    }
}

注意:

FileWriter写完数据之后,必须刷新或者关闭,写出去的数据才能生效。

缓冲流
  • 读数据时:它先用原始字节输入流一次性读取8KB的数据存入缓冲流内部的数组中(囤货),再从8KB的字节数组中读取一个字节或者多个字节(消耗囤货)。

  • 写数据时: 它是先把数据写到缓冲流内部的8BK的数组中(ps: 先攒一车货),等数组存满了,再通过原始的字节输出流,一次性写到目标文件中去(把囤好的货,一次性运走)。

定义格式:

//字节缓冲输入流
new BufferedInputStream(new FileInputStream("D:\\钗头凤·红酥手.txt"))
//字节缓冲输出流
new BufferedOutputStream(new FileOutputStream("D:\\钗头凤·红酥手(副本).txt"))
//字符缓冲输入流
new BufferedReader(new FileReader("D:\\钗头凤·红酥手.txt"));
//字符缓冲输出流
new BufferedWriter(new FileWriter("D:\\钗头凤·红酥手(副本).txt"));
打印流

所见即所得

示例代码:

//字节打印流
public static void main(String[] args) throws Exception {
    //字节打印流,向指定文件写出数据
    PrintStream ps = new PrintStream("D:\\ps.txt");

    ps.write(97);//写入一个字节,结果为97
    ps.write("hello".getBytes());//写字节数组

    ps.println("这是使用PrintStream打印流写出的数据");

    //关闭资源
    ps.close();
}

//字符打印流
public static void main(String[] args) throws Exception {
    //字节打印流,向指定文件写出数据
    PrintWriter pw = new PrintWriter("D:\\pw.txt");

    pw.write(97);//写入一个字节
,结果为97
    pw.write("hello");//写字符数据

    pw.println("这是使用PrintWriter打印流写出的数据");
    //关闭资源
    pw.close();
}
序列化流
概念

序列化:意思就是把java对象转为字节数据写到文件或者网络中去。(简单记:写对象)

反序列化:意思就是把对象从文件或者网络中读取出来。(简单记:读对象)

ObjectOutputStream–序列化

示例代码:

//定义一个User类
public class User implements Serializable {
    private int id;
    private String name;
    public User() {
    }
    public User(int id, String name) {
        this.id = id;
        this.name = name;
    }
    public int getId() {
        return id;
    }
    
    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String toString() {
        return "User{id = " + id + ", name = " + name + "}";
    }
}

//定义一个Demo测试类
public class Demo {
    public static void main(String[] args) throws Exception {
        //将对象转为字节存储---序列化,要序列化的类必须实现序列化接口
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("test.per"));

        //将user对象序列化到文件中
        oos.writeObject(new User(1,"小明"));
        oos.close();

        //反序列化
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("java_ee\\test.per"));

        //读取文件中的字节数据,并且反序列化为java对象
        User user = (User) ois.readObject();
        System.out.println(user);
        ois.close();
    }
}
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

给TA打赏
共{{data.count}}人
人已打赏

多线程

2024-4-3 16:08:21

多线程

2024-4-3 16:08:21

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索