文件io基础

文件

流:数据在数据源(文件)和程序(内存)之间经历的路径

输入流:数据从数据源(文件)到程序(内存)的路径

输出流:数据从程序(内存)到数据源(文件)的路径

创建文件

  1. new File(String pathname) //根据路径构建一个File对象

    public void create01() {
        String filePath = "d:\\demo01.txt";
        File file = new File(filePath);
        try {
            file.createNewFile();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
  2. new File(File parent, String child) //根据父目录文件+子路径构建

    public void create02() {
        File root = new File("d:\\");
        String fileName = "demo02.txt";
        File file = new File(root, fileName);
        try {
            file.createNewFile();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
  3. new File(String parent, String child) //根据父目录+子路径构建

    public void create03() {
        String parentPath = "d:\\";
        String filePath = "demo03.txt";
        File file = new File(parentPath, filePath);
        try {
            file.createNewFile();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    

获取文件的相关信息

public void getInfo() {
    // 获取文件
    String filePath = "d:\\demo01.txt";
    File file = new File(filePath);

    // 文件名
    System.out.println(file.getName());
    // 绝对路径
    System.out.println(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());
}

image-20210924093518915

目录操作

删除文件

// 判断 d:\\demo01.txt是否存在 存在则删除
@Test
public void m1() {
    String filePath = "d:\\demo01.txt";
    File file = new File(filePath);
    if (file.exists()) {
        if (file.delete()) {
            System.out.println("删除成功");
        }
    }
}

删除目录

// 判断 d:\\demo01 是否存在 存在则删除
@Test
public void m2() {
    String filePath = "d:\\demo01.txt";
    File file = new File(filePath);
    if (file.exists()) {
        if (file.delete()) {
            System.out.println("删除成功");
        }
    } else {
        System.out.println("该目录不存在");
    }
}

创建多级目录

// 判断 d:\\demo\\a\\b\\c 是否存在 不存在则创建
@Test
public void m3() {
    String dirPath = "d:\\demo\\a\\b\\c";
    File file = new File(dirPath);
    if (file.exists()) {
        System.out.println("该目录存在");
    } else {
        // 创建一级目录是mkdir() 多级目录是mkdirs()
        if (file.mkdirs()) {
            System.out.println("目录创建成功");
        } else {
            System.out.println("目录创建失败");
        }
    }
}

InputStream

FileInputStream

单个字节的读取

public void readFile01() {
    String filePath = "d:\\hello.txt";
    int readData = 0;
    FileInputStream fileInputStream = null;
    try {
        // 创建fileInputStream对象
        fileInputStream = new FileInputStream(filePath);
        // 如果返回-1读取完毕
        while ((readData = fileInputStream.read()) != -1) {
            System.out.println((char) readData);
        }
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            fileInputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

如果文件中有中文文字,则会出现乱码

因为在utf-8中 一个文字是由3个字节构成的 而read读取时每次只会读取一个字节

多个字节读取

// 采用read(byte[] b) 读取文件 提高效率
@Test
public void readFile02() {
    String filePath = "d:\\hello.txt";
    byte[] bytes = new byte[8]; //一次读取8个字节
    int readLen = 0;
    FileInputStream fileInputStream = null;
    try {
        // 创建fileInputStream对象
        fileInputStream = new FileInputStream(filePath);
        // fileInputStream.read(bytes) 返回实际读取的个数
        while ((readLen = fileInputStream.read(bytes)) != -1) {
            System.out.println(new String(bytes, 0, readLen));
        }
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            fileInputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

image-20210924101739099

OutputStream

FIleOutputStream

// 在文件a.txt中写入hello,world 如果文件不存在则创建
@Test
public void writeFIle() {
    // 创建文件流
    FileOutputStream fileOutputStream = null;

    String filePath = "d:\\a.txt";
    try {
        fileOutputStream = new FileOutputStream(filePath);

        //fileOutputStream.write('h'); //写入单个字符
        String str = "hello,world";
        fileOutputStream.write(str.getBytes());

    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            fileOutputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

image-20210924102800567

// new FileOutputStream(filePath) 会覆盖原来的内容
// new FileOutputStream(filePath, true) 当写入内容时 是追加到文件后面
fileOutputStream = new FileOutputStream(filePath, true);

image-20210924103154225

拷贝文件

public class FileCopyDemo {
    public static void main(String[] args) {
        // 1.创建文件的输入流 将文件读取到程序
        FileInputStream fileInputStream = null;
        // 2.创建文件的输出流 将文件存储到相应位置
        FileOutputStream fileOutputStream = null;

        String inputPath = "C:\\Users\\81288\\Pictures\\wx.jpg";
        String outputPath = "D:\\wx.jpg";

        try {
            fileInputStream = new FileInputStream(inputPath);
            fileOutputStream = new FileOutputStream(outputPath);

            byte[] bytes = new byte[1024]; //创建字节数组 提高读取效率
            int readLen = 0;
            while ((readLen = fileInputStream.read(bytes)) != -1) {
                // 读取到后就写入
                fileOutputStream.write(bytes, 0, readLen);
            }

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

FileReader

public class FileReaderDemo01 {
    public static void main(String[] args) {
        String filePath = "d:\\b.txt";
        // 1. 创建FileReader对象
        FileReader fileReader = null;
        try {
            fileReader = new FileReader(filePath);
            int data = 0;
            int readLen = 0;
            char[] buf = new char[8];
            //data = fileReader.read() 单个字符读取
            while ((readLen = fileReader.read(buf)) != -1) {
                System.out.println(new String(buf, 0, readLen));
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fileReader != null) {
                try {
                    fileReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

image-20210924105755150

FileWriter

public class FileWriterDemo01 {
    public static void main(String[] args) {
        String filePath = "d:\\c.txt";
        FileWriter writer = null;

        try {
            //new FileWriter(filePath); 覆盖内容
            //new FileWriter(filePath, true); 追加内容
            writer = new FileWriter(filePath, true);

            //写入单个字符
            writer.write('S');
            //写入指定数组
            char[] chars = {'A', 'B', 'C'};
            writer.write(chars);
            //写入指定数组的指定部分
            writer.write("Legend never die".toCharArray(), 0, 6);
            //写入字符串
            writer.write("茶楼");
            //写入部分字符串
            writer.write("多余的解释", 3, 2);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 一定要 close() 或 flush() 才会真正写入到文件
            try {
                writer.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

image-20210924110838695

节点流和处理流

节点流可以从一个特定的数据源读写顺序 如FileReader FileInputStream

处理流(包装流)是**“连接”在已存在的流**(节点流或处理流)之上 为程序提供更为强大的读写功能 也更加灵活 如BufferedReader BufferedWriter

区别和联系:

  1. 节点流是底层流 直接和数据源相连
  2. 处理流包装节点流 既可以消除不同节点流的实现差异 也可以提供更方便的方法完成输入输出
  3. 处理流对节点流进行包装 使用了修饰器设计模式 不会直接与数据源相连

BufferedReader

public class FileReaderDemo02 {
    public static void main(String[] args) throws IOException {
        String filePath = "d:\\c.txt";
        // 创建BufferedReader对象
        BufferedReader bufferedReader = new BufferedReader(new FileReader(filePath));

        //readLine() 按行读取文件 当返回为空时读取完毕
        String line = null;
        while ((line = bufferedReader.readLine()) != null) {
            System.out.println(line);
        }

        // 关闭流 只需要关闭外层流
        bufferedReader.close();
    }
}

image-20210924142253857

BufferedWriter

public class FileWriterDemo02 {
    public static void main(String[] args) throws IOException {
        String filePath = "d:\\c.txt";

        // 创建BufferedWriter对象
        // new FileWriter(filePath, true) 追加写入
        BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(filePath, true));
        bufferedWriter.write("犯我德邦者虽远必诛");
        bufferedWriter.newLine(); //插入换行
        bufferedWriter.write("德玛西亚!");

        // 关闭外层流
        bufferedWriter.close();
    }
}

image-20210924142851757

拷贝文件2.0

// 拷贝文本文件
public class FileCopyDemo02 {
    public static void main(String[] args) {
        String inputPath = "d:\\c.txt";
        String outputPath = "d:\\d.txt";

        BufferedReader br = null;
        BufferedWriter bw = null;
        String readLine;

        try {
            br = new BufferedReader(new FileReader(inputPath));
            bw = new BufferedWriter(new FileWriter(outputPath));
            while ((readLine = br.readLine()) != null) {
                bw.write(readLine);
                bw.newLine(); // 读取一行内容但是没有换行
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                br.close();
                bw.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

image-20210924143414059

拷贝文件3.0

// 拷贝图片
public class InputStreamDemo02 {
    public static void main(String[] args) {
        String inputPath = "C:\\Users\\81288\\Pictures\\wx.jpg";
        String outputPath = "d:\\wx.jpg";
        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;

        try {
            bis = new BufferedInputStream(new FileInputStream(inputPath));
            bos = new BufferedOutputStream(new FileOutputStream(outputPath));

            byte[] buff = new byte[1024];
            int readLen = 0;

            while ((readLen = bis.read(buff)) != -1) {
                bos.write(buff, 0, readLen);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                bis.close();
                bos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

ObjectInputStream

保存值和数据类型 称为序列化 是处理流

为了让某个类是可序列化的 该类必须实现Serializable 或 Externalizable 接口

推荐使用Serializable接口 该接口是一个标记接口 不需要实现方法

序列化对象时 不会序列化 static 和 transient 修饰的成员

序列化对象时 要求里面的属性类型也需要实现序列化接口

public class OutputStreamDemo02 {
    public static void main(String[] args) throws Exception {
        // 序列化后保存的文件格式不是纯文本 而是按照其他格式保存
        String filePath = "d:\\data.dat";

        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(filePath));

        // 序列化数据到文件中
        oos.writeInt(100); // int -> Integer Integer实现了Serializable接口
        oos.writeBoolean(true);
        oos.writeChar('a');
        oos.writeDouble(9.5);
        oos.writeUTF("德玛西亚!");

        oos.writeObject(new Dog("小黄", 10));

        oos.close();

    }
}
class Dog implements Serializable {
    private String name;
    private int age;

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

    @Override
    public String toString() {
        return "Dog{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

ObjectOutputStream

读取值和数据类型 称为反序列化 是处理流

public class InputStreamDemo03 {
    public static void main(String[] args) throws Exception {
        String path = "d:\\data.dat";

        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(path));

        // 读取顺序要和存放顺序一致
        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());
        Object o = ois.readObject();
        // Dog dog = (Dog) o; 如果需要使用Dog的方法 需要向下转型
        // 需要我们将Dog类的定义 拷贝到可以引用的位置
        System.out.println(ois.readObject());

        ois.close();

    }
}

image-20210924152311213

转换流

字节流 -> 字符流

有时候文本文档采用的编码格式不是UTF-8 此时从文本文档中读取数据会出现乱码情况

而字节流可以处理不同编码格式的文件 因此可以采用字节流处理然后转换为字符流

public class TransformDemo {
    public static void main(String[] args) throws IOException {
        // 使用InputStreamReader 解决中文乱码问题
        String path = "d:\\gbk.txt";
        // 把FileInputStream 转成 InputStreamReader
        // 指定编码 gbk
        InputStreamReader isr = new InputStreamReader(new FileInputStream(path), "gbk");
        // 把InputStreamReader 传入 BufferedReader
        BufferedReader br = new BufferedReader(isr);
        // 读取
        String s = br.readLine();
        System.out.println(s);

        // 关闭外层流
        br.close();
    }
}

image-20210924162328746

image-20210924162352556

public class TransformDemo02 {
    public static void main(String[] args) throws IOException {
        // 把FileOutputStream 转换为 字符流
        String path = "d:\\gbk2.txt";
        OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(path), "gbk");
        osw.write("哈哈哈abc");

        osw.close();
    }
}

image-20210924163033470

打印流

打印流只有输出流 没有输入流

字节打印流

public class PrintDemo01 {
    public static void main(String[] args) throws IOException {
        // 在默认情况下 PrintStream 输出数据的位置是标准输出 即显示器
        PrintStream out = System.out;
        out.print("hello, world");
        // print底层采用write() 所以我们可以直接调用write进行打印
        out.write("fire fire".getBytes());

        // 修改打印流输出的位置 d:\printOut.txt
        System.setOut(new PrintStream("d:\\printOut.txt"));
        System.out.println("呦呦切克闹");

        out.close();
    }
}

image-20210924164143130

image-20210924164038168

字符打印流

public class PrintDemo02 {
    public static void main(String[] args) throws IOException {
        //PrintWriter printWriter = new PrintWriter(System.out);
        //printWriter.print("hello, world!");

        //打印到文件中
        PrintWriter printWriter = new PrintWriter(new FileWriter("d:\\printOut02.txt"));
        printWriter.write("小哥哥快来玩呀");

        printWriter.close();

    }
}

image-20210924164758213

Properties

键值对不需要有空格 值不需要引号起来 默认类型是String

读取内容

public class PropertiesDemo01 {
    public static void main(String[] args) throws IOException {
        // 读取mysql.properties文件

        // 1.创建对象
        Properties properties = new Properties();
        // 2.加载指定配置文件
        properties.load(new FileReader("src\\mysql.properties"));
        // 3.显示键值对
        properties.list(System.out);
        // 4.根据key获取对应值
        System.out.println("用户名: " + properties.getProperty("user"));

    }
}

image-20210924170750568

修改内容

public class PropertiesDemo02 {
    public static void main(String[] args) throws IOException {
        // 修改mysql.properties文件

        // 1.创建对象
        Properties properties = new Properties();
        // 2.设置属性
        // 如果该文件没有key 就是创建 如果有则替换
        properties.setProperty("charset", "utf8");
        properties.setProperty("level", "top");
        properties.setProperty("user", "汤姆"); // 保存的是Unicode码
        // 3.将k-v存储到文件中
        // null处传入注释 如果设为null则没有注释
        properties.store(new FileOutputStream("src\\mysql.properties"), "comment");
    }
}

image-20210924171153163

("用户名: " + properties.getProperty(“user”));

}

}


[外链图片转存中...(img-2UyN26FO-1632474810088)]



修改内容

```java
public class PropertiesDemo02 {
    public static void main(String[] args) throws IOException {
        // 修改mysql.properties文件

        // 1.创建对象
        Properties properties = new Properties();
        // 2.设置属性
        // 如果该文件没有key 就是创建 如果有则替换
        properties.setProperty("charset", "utf8");
        properties.setProperty("level", "top");
        properties.setProperty("user", "汤姆"); // 保存的是Unicode码
        // 3.将k-v存储到文件中
        // null处传入注释 如果设为null则没有注释
        properties.store(new FileOutputStream("src\\mysql.properties"), "comment");
    }
}

[外链图片转存中…(img-hqQsIHtO-1632474810088)]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值