Java05

文件

文件基础知识

文件是保存数据的地方
输入流、输出流是以java程序(内存)为参考
在这里插入图片描述

创建文件的三种方式

目录可以理解为文件夹

package file_;

import org.junit.jupiter.api.Test;

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

public class FileCreate {
    public static void main(String[] args) {

    }

    // 方式1 new File(String pathname)
    @Test
    public void create01(){
        String filePath = "G:\\Java\\代码\\study1\\news1.txt";
        File file = new File(filePath);

        try {
            file.createNewFile();
            System.out.println("程序创建成功");
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    // 方式2 new File(File parent, String child) 根据父目录文件+子路径构建    子目录也就是文件名
    @Test
    public void create02(){
        File parentFile = new File("G:\\Java\\代码\\study1\\");     // 创建一个File对象,只是在内存里有了对象,但并没有和硬盘发生关系
        String fileName = "news02.txt";
        File file1 = new File(parentFile, fileName);
        try {
            file1.createNewFile();      // 这里才是真正创建文件,这时才会把信息写入硬盘
            System.out.println("成功");
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

    }

    // 方式3 new File(String parent, String child) 根据父目录+子路径构建
    @Test
    public void vreate03(){
        String parentPath = "G:\\Java\\代码\\study1\\";
        String filePath = "news03.txt";
        File file = new File(parentPath, filePath);
        try {
            file.createNewFile();
            System.out.println("成功!");
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

}

获取文件信息

package file_;

import org.junit.jupiter.api.Test;

import java.io.File;

public class FileInformation {
    public static void main(String[] args) {

    }


    @Test
    // 获取文件信息
    public void info(){
        // 创建文件对象
        File file = new File("G:\\Java\\代码\\study1\\news1.txt");

        // 调用相应的方法,得到对应信息
        System.out.println("fileName:" +file.getName());

        System.out.println("absolutePath:" + file.getAbsolutePath());
        System.out.println("文件父级目录:" + file.getParent());
        System.out.println("文件大小(字节)" + file.length());
        System.out.println("文件是否存在" + file.exists());
        System.out.println("文件是不是一个文件" + file.isFile());
        System.out.println("文件是不是一个目录" + file.isDirectory());       // False
        
    }
}

目录的操作和文件删除

  • mkdir创建一级目录
  • mkdirs创建多级目录
  • delete删除空目录或删除文件
  1. I/O用于处理数据传输,如读写文件,网络通讯等
  2. Java程序中,对于数据的输入/输出操作以"流(stream)"的方式进行
  3. java.io包下提供了各种"流"类和接口,用以获取不同种类的数据,并通过方法输入或输出数据

在这里插入图片描述

  • 文件输入(读取文件)
package file_.inputstream_;

import org.junit.jupiter.api.Test;

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

/**
 * FileInputStream的使用(字节输入流)
 * 也就是文件 -- > 程序
 */
public class FileInputStream_ {
    public static void main(String[] args) {

    }



    @Test
    public void readFile01(){
        String filePath = "G:\\Java\\代码\\study1\\news1.txt";
        int readData = 0;
        FileInputStream fileInputStream = null;
        try {
            // 创建FileInputStream对象,用于读取文件
            fileInputStream = new FileInputStream(filePath);
            // 从该输入流读取一个字节的数据,如果返回-1,表示读取完毕
           while ((readData = fileInputStream.read()) != -1){
               System.out.print((char) readData);     // 因为读取得到的是int,返回char输出显示
               // 汉字读取的时候会出现乱码的问题,因为如果utf8,一个汉字由三个字节组成,而这个每次只能读取一个字节
           }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 关闭文件流,释放资源
            try {
                fileInputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }


    @Test
    public void readFile02(){
        String filePath = "G:\\Java\\代码\\study1\\news1.txt";
        int readData = 0;

        // 创建一个字节数组
        byte[] buf = new byte[8];
        int readLen = 0;
        FileInputStream fileInputStream = null;
        try {

            fileInputStream = new FileInputStream(filePath);
            // 每次最多读取buf长度个字节,返回值是读取的长度(末尾的时候可能不到8),
            while ((readLen = fileInputStream.read(buf)) != -1){
                System.out.println(new String(buf, 0, readLen));   // 将读取的内容转化为字符串输出

            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 关闭文件流,释放资源
            try {
                fileInputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }
}

  • 文件输出(写入文件)
package file_.outputstream_;

import org.junit.jupiter.api.Test;

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

/**
 * 将数据写到文件中,如果该文件不存在,则创建该文件
 */
public class FileOutputStream01 {
    public static void main(String[] args) {

    }

    @Test
    public void writeFile(){
        // 创建FileOutputStream对象
        String filePath = "G:\\Java\\代码\\study1\\news02.txt";
        FileOutputStream fileOutputStream = null;
        try {
            /**
             * new FileOutputStream(filePath)创建方式,当写入内容时,会覆盖原来的内容
             * new FileOutputStream(filePath, true)创建方式,这种方式写入内容是在末尾,追加到文件后面,不会覆盖
             */

            fileOutputStream = new FileOutputStream(filePath);
            /**
             * 3种方式
             */
//            fileOutputStream.write('a');      // 只能写入单个字节
            String str = "hello, world";
//            fileOutputStream.write(str.getBytes());     // str.getBytes() 把可以把字符串转成byte数组
            fileOutputStream.write(str.getBytes(), 0, 5);
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            try {
                fileOutputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

  • 文件拷贝(文件读写)
package file_.outputstream_;

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

public class FileCopy {
    public static void main(String[] args) {
        /**
         * 完成文件拷贝
         * 思路:
         * 1. 创建文件的输入流,将文件读取到程序
         * 2. 创建文件的输出流,将读取到的文件数据,写入到指定的文件
         */
        String srcFilePath = "C:\\Users\\Mango\\Desktop\\img\\dog.jpeg";
        String destFilePath = "G:\\Java\\代码\\study1\\dog.jpeg";
        FileInputStream fileInputStream = null;
        FileOutputStream fileOutputStream = null;

        try {
            fileInputStream = new FileInputStream(srcFilePath);
            fileOutputStream = new FileOutputStream(destFilePath);
            // 定义一个字节数组,提高读取效果
            byte[] buf = new byte[1024];
            int readLen = 0;
            while ((readLen = fileInputStream.read(buf)) != -1){
                // 读取到后,就写入到文件,边读边写
                fileOutputStream.write(buf, 0, readLen);
            }
            System.out.println("拷贝成功");

        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            // 关闭输入流和输出流,释放资源
            try {
                if (fileInputStream != null) {
                    fileInputStream.close();
                }
                if (fileOutputStream != null){
                    fileOutputStream.close();
                }
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

  • FileReader和FileWriter是字符流,即按照字符来操作io
  • FileReader
package file_.reader_;

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

public class FileReader_ {
    public static void main(String[] args) {
        String filePath = "G:\\Java\\代码\\study1\\story.txt";
        FileReader fileReader = null;
        char[] chars = new char[100];
        int charLen = 0;
        try {
            fileReader = new FileReader(filePath);
            while ((charLen = fileReader.read(chars)) != -1){
                System.out.print(new String(chars, 0, charLen));
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            if (fileReader != null) {
                try {
                    fileReader.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }

    }
}

package file_.writer_;

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

public class FileWriter_ {
    public static void main(String[] args) {
        String filePath = "G:\\Java\\代码\\study1\\news02.txt";
        FileWriter fileWriter = null;
        try {
            fileWriter = new FileWriter(filePath);
            fileWriter.write("hah哈哈哈");
            System.out.println("成功");
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            if (fileWriter != null){
                try {
                    fileWriter.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }
}

节点流和处理流

  • 节点流可以从一个特点的数据源读写文件,如FileReader、FileWriter
  • 处理流(也叫包装流)是“连接”在已存在的流(节点流或处理流)之上,为程序提供更为强大的读写功能,如BufferedReader、BufferedWriter
  • BufferReader的使用
package file_.reader_;

import java.io.BufferedReader;
import java.io.FileReader;

/**
 * BufferedReader的使用
 */
public class BufferReader_ {
    public static void main(String[] args) throws Exception{
        String filePath = "G:\\Java\\代码\\study1\\story.txt";
        BufferedReader bufferedReader = new BufferedReader(new FileReader(filePath));
        String line;
        // 当返回null时,
        while ((line = bufferedReader.readLine()) != null) {     // 按行读取
            System.out.println(line);
        }

        // 关闭流,这里注意,只需要关闭BufferedReader,因为底层会自动关闭 节点流 (FileReader)
        bufferedReader.close();
    }
}

  • BufferedWriter的使用
package file_.writer_;

import javax.imageio.IIOException;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;

/**
 * BufferedWriter使用
 */
public class BufferWriter_ {
    public static void main(String[] args) throws IOException {
        String filePath = "G:\\Java\\代码\\study1\\bufferWriter.txt";
        BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(filePath, true));     // 同样,可选择是否是追加模式添加内容
        bufferedWriter.write("hello,mango,冲!");
        bufferedWriter.newLine();   // 插入一个换行符
        bufferedWriter.write("hello,mango,冲!");
        bufferedWriter.newLine();
        bufferedWriter.write("hello,mango,冲!");
        // 关闭外层流即可,传入的new FileWriter(filePath)会在底层关闭
        bufferedWriter.close();
    }
}

  • 练习
package file_.writer_;

import java.io.*;

/**
 * BufferedReader和BufferedWriter注意不要去操作 二进制文件【视频、声音、doc、PDF等】,可能造成文件损坏
 * 它们是处理字符的
 *
 * 如果要处理二进制文件,使用BufferedInputStream和BufferedOutputStream
 */
public class BufferedCopy_ {
    public static void main(String[] args) {
        String srcFilePath = "G:\\Java\\代码\\study1\\bufferWriter.txt";
        String destFilePath = "G:\\Java\\代码\\study1\\bufferWriter_copy.txt";


        BufferedReader bufferedReader = null;
        BufferedWriter bufferedWriter = null;
        String line;
        try {
            bufferedReader = new BufferedReader(new FileReader(srcFilePath));
            bufferedWriter = new BufferedWriter(new FileWriter(destFilePath));
            while ((line = bufferedReader.readLine()) != null) {        // readLine()是读取一行的内容,但是没有换行
                bufferedWriter.write(line);
                bufferedWriter.newLine();
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            try {
                if (bufferedReader != null) {
                    bufferedReader.close();
                }
                if (bufferedWriter != null) {
                    bufferedWriter.close();
                }
            } catch (IOException e) {
                throw new RuntimeException(e);
            }


        }
    }
}

  • 处理字节
package file_.writer_;

import java.io.*;

/**
 * BufferedOutputStream 和 BufferedInputStream的使用
 */
public class BufferedCopy02 {
    public static void main(String[] args) {
        String srcFilePath = "G:\\Java\\代码\\study1\\dog.jpeg";
        String destFilePath = "G:\\Java\\代码\\study1\\dog_copy.jpeg";

        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;

        try {
            bis = new BufferedInputStream(new FileInputStream(srcFilePath));
            bos = new BufferedOutputStream(new FileOutputStream(destFilePath));
            byte[] buff = new byte[1024];
            int readLen = 0;
            while ((readLen = bis.read(buff)) != -1){
                bos.write(buff, 0, readLen);
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            try {
                if (bis != null){
                    bis.close();
                }
                if (bos != null){
                    bos.close();
                }
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }

}

  • 序列化和反序列化
  1. 序列化就是在保存数据时,保存数据的值和数据类型
  2. 反序列化就是在恢复数据时,恢复数据的值和数据类型
  3. 需要让某个对象支持序列化机制,则必须让其类是可序列化的,为了让某个类是可序列化的,该类必须实现如下两个接口之一:
  • Serializable(一般使用这个)
  • Externalizable

序列化

package file_.outputstream_;

import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

public class ObjectOutStream_ {
    public static void main(String[] args) throws Exception{
        // 序列化后,保存的文件格式,不是纯文本,而是按照它的格式来保存
        String filePath = "G:\\Java\\代码\\study1\\data.dat";
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(filePath));

        // 序列化数据到G:\Java\代码\study1\data.dat
        oos.write(100);     // 自动装箱 int -> Integer(Integer实现了Serializable)
        oos.writeBoolean(true);     // 自动装箱 boolean -> Boolean(Boolean实现了Serializable)
        oos.writeChar('a');
        oos.writeDouble(9.5);
        oos.writeUTF("haha冲");
        oos.writeObject(new Dog("ka", 2));      // 注意要保证其可序列化 即实现接口

        oos.close();
        System.out.println("数据保存完毕(序列化形式)");

    }
}

// 如果需要序列化某个类的对象,必须实现Serializable接口
class Dog implements Serializable {
    private String name;
    private int age;

    public Dog(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

反序列化

package file_.outputstream_;

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

public class ObjectInputStream_ {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        String filePath = "G:\\Java\\代码\\study1\\data.dat";
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(filePath));
        /**
         * 读取
         * 读取(反序列化)的顺序需要和保存数据(序列化)的顺序一致
         */
        System.out.println(ois.readInt());
        System.out.println(ois.readBoolean());
        System.out.println(ois.readChar());
        System.out.println(ois.readDouble());
        System.out.println(ois.readUTF());
        System.out.println(ois.readObject());
        // 关闭流,关闭外层流即可,底层会关闭FileInputStream
        ois.close();
    }
}

Properties类:
1)专门用于读取配置文件的集合类
配置文件的格式:键=值
2)注意:键值对不需要有空格,值不需要用引号引起来,默认类型是String

常见方法:

  • load:加载配置文件的键值对到Properties对象
  • list:将数据显示到指定设备/流对象
  • getProperty(key):根据键获取值
  • setProperty(key,value):设置键值到Properties对象
  • store:将Properties中的键值对存储到配置文件,在IDEA中,保存信息到配置文件,如果含有中文,会存储为Unicode码
  1. 读取配置文件
package properties;

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

public class Properties02 {
    public static void main(String[] args) throws IOException {
        // 使用Properties类来读取mysql.properties文件
        Properties properties = new Properties();
        // 加载指定的配置文件
        properties.load(new FileReader("src/properties/mysql.properties"));
        // 把k-v显示在控制台
        properties.list(System.out);

        String ip = properties.getProperty("ip");
        System.out.println(ip);

    }
}

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值