java中文件和流的基本操作

一、文件操作

(一)文件创建的三种常用方式

package com.yang;

import org.junit.Test;

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

public class FileCreate {


    /**
     * 创建文件方式1:指定文件的全路径
     */
    @Test
    public void fileCreate01(){
        File file = new File("e:\\io\\news.txt");
        try {
            file.createNewFile();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 创建文件方式2:指定目录下和文件名
     */
    @Test
    public void fileCreate02(){
        File file = new File("e:\\io\\", "news2.txt");
        try {
            file.createNewFile();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 创建文件方式3:指定一个File对象(目录)和文件名
     */
    @Test
    public void fileCreate03(){
        File parentFile = new File("e:\\io\\");
        File file = new File(parentFile, "news3.txt");
        try {
            file.createNewFile();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}

(二)File类常用API

package com.yang;

import org.junit.Test;

import java.io.File;

public class FileAPI {

    @Test
    public void testFileAPI(){
        File file = new File("e:\\io\\news.txt");
        System.out.println(file.exists()); // 文件是否存在
        System.out.println(file.getName()); // 获取文件名
        System.out.println(file.getParent()); // 获取文件所在目录
        System.out.println(file.getAbsolutePath()); // 获取文件全路径
        System.out.println(file.isFile()); // 是否是一个文件
        System.out.println(file.isDirectory()); // 是否是一个目录
        System.out.println(file.length()); // 文件的大小(字节)
    }
}

(三)创建目录和删除目录

package com.yang;

import org.junit.Test;

import java.io.File;

public class Directory {

    /**
     * 创建一级目录
     */
    @Test
    public void directoryTest(){
        File file = new File("e:\\io\\demo");
        // 如果该目录不存在,就创建
        if (!file.exists()){
            // mkdir方法用来创建一级目录
            file.mkdir();
        }
    }

    /**
     * 创建多级目录
     */
    @Test
    public void directoryTest02(){
        File file = new File("e:\\io\\a\\b\\c");
        // 如果该目录不存在,就创建
        if (!file.exists()){
            // mkdirs方法用来创建一级目录
            file.mkdirs();
        }
    }

    /**
     * 删除目录和文件
     */
    @Test
    public void testDelete(){
        File file = new File("e:\\io\\news.txt");
        if (file.exists()){
            file.delete();
        }
    }

    /**
     * 删除目录时,不能直接删除嵌套目录(如果该目录有子目录或子文件,不能直接删除)
     */
    @Test
    public void testDelete02(){
        File file = new File("e:\\io\\a");
        if (file.exists()){
            file.delete();
        }
    }
}

二、输入输出流

认识四个抽象类:

  1. InputStream 字节输入流
  2. OutputStream 字节输出流
  3. Reader 字符输入流
  4. Writer 字符输出流

(一)InputStream

1.FileInputStream

常用API:

int read() // 一次读取一个字节,效率低
int read(byte b[]) // 读取一个字节数组(读取多个字节),效率高

测试:

package com.yang.inputstream_;

import org.junit.Test;

import java.io.FileInputStream;
import java.io.IOException;

public class TestFileInputStream {

    @Test
    public void test(){
        FileInputStream fis = null;
        int readData = 0;

        try {
            // 获取FileInputStream对象,用于读取文件的字节输入流对象
            fis = new FileInputStream("e:\\io\\demo01.txt");

            // read() 将读取到的字节对应的十进制码值(ASCLL码)返回,当该方法返回-1时,说明读取完成
            while ((readData = fis.read()) != -1){
                System.out.print((char)readData);
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            try {
                fis.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }

    @Test
    public void test02(){
        FileInputStream fis = null;
        byte[] data = new byte[8]; // 指定一次最大读取8个字节
        int len = 0;

        try {
            // 获取FileInputStream对象,用于读取文件的字节输入流对象
            fis = new FileInputStream("e:\\io\\demo01.txt");

            // read(byte b[]) 将实际读取到的字节数量返回,当该方法返回-1时,说明读取完成
            while ((len = fis.read(data)) != -1){
                System.out.print(new String(data,0,len));
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            try {
                fis.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }
}
2.BufferedInputStream

使用方式和BufferedReader类似,但是该类偏向于操作二进制文件

3.ObjectInputStream

序列化和反序列化:

  1. 序列化:在保存数据时,保存数据的值和数据类型
  2. 反序列化:在恢复数据时,恢复数据的值和数据类型
  3. 如果需要一个类能够实现序列化机制,需要实现两个接口之一
    • Serializable
    • Externalizable
package com.yang.inputstream_;

import org.junit.Test;

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

public class TestObjectInputStream {

    @Test
    public void test(){
        ObjectInputStream ois = null;

        try {
            // 反序列化时需要注意每个值在序列化时的顺序,反序列化时的顺序和序列化时的顺序要一致
            ois = new ObjectInputStream(new FileInputStream("e:\\io\\obj.dat"));
            System.out.println(ois.readInt());
            System.out.println(ois.readFloat());
            System.out.println(ois.readChar());
            System.out.println(ois.readUTF());
            Object obj = ois.readObject();
            System.out.println(obj);
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            if (ois != null){
                try {
                    ois.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }
}

注意:

反序列化时需要注意每个值在序列化时的顺序,反序列化时的顺序和序列化时的顺序要一致

(二)OutputStream

1.FileOutputStream

当向文件中写入数据时,如果该文件不存在,则会自动创建该文件
常用API:

void write(int b) // 写入单个字节
void write(byte b[]) // 写入一个字节数组(多个字节)
void write(byte b[], int off, int len) // 写入一个字节数组的部分数据

测试:

package com.yang.outputstream_;

import org.junit.Test;

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

public class TestFileOutputStream {

    @Test
    public void test(){

        FileOutputStream fos = null;
        try {
            // 使用FileOutputStream(String name),默认写入的内容会覆盖原来内容
            fos = new FileOutputStream("e:\\io\\output.txt"); // 获取输出流对象
            // write(int b) 写入单个字节
            fos.write('Y');
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            try {
                fos.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }

    @Test
    public void test02(){

        FileOutputStream fos = null;
        try {
            // 只传入一个字符串时,默认写入数据时会覆盖文件原有数据
            fos = new FileOutputStream("e:\\io\\output.txt"); // 获取输出流对象
            // write(byte b[]) 将一个字节数组写入到文件中
            fos.write("hello,world".getBytes()); // getBytes方法将字符串转为字节数组
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            try {
                fos.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }

    @Test
    public void test03(){

        FileOutputStream fos = null;
        try {
            // 使用FileOutputStream(String name, boolean append)并设置为true时,默认在文件内容末尾追加
            fos = new FileOutputStream("e:\\io\\output.txt",true); // 获取输出流对象
            // write(byte b[], int off, int len) 将一个字节数组的部分写入到文件中,从0开始为第一个字符,取len个字符,取不到第len个
            fos.write("hello,yang".getBytes(),0,5); // getBytes方法将字符串转为字节数组
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            try {
                fos.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }
}
文件拷贝
package com.yang.outputstream_;

import org.junit.Test;

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

public class FileCopy {

    @Test
    public void fileCopy(){
        // 创建文件输入输出流
        FileInputStream fis = null;
        FileOutputStream fos = null;

        try {
            // 边读边写,效率更高
            fis = new FileInputStream("d:\\xiazai\\image1.png");
            fos = new FileOutputStream("e:\\io\\image1.png");

            int dataLen = 0;
            byte[] dataArr = new byte[1024];
            while((dataLen = fis.read(dataArr)) != -1){
                fos.write(dataArr,0,dataLen); // 这里使用write(byte b[], int off, int len)避免拷贝的文件出错
            }
            System.out.println("拷贝完成...");

        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            try {
                if (fis != null){
                    fis.close();
                }
                if (fos != null){
                    fos.close();
                }
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }
}
2.BufferedOutputStream

使用方式和BufferedWriter类似,但是该类偏向于操作二进制文件

文件拷贝
package com.yang.outputstream_;

import org.junit.Test;

import java.io.*;

public class FIleCopy02 {

    @Test
    public void test(){
        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;

        try {
            bis = new BufferedInputStream(new FileInputStream("e:\\io\\image1.png"));
            bos = new BufferedOutputStream(new FileOutputStream("e:\\io\\image2.png"));

            byte[] data = new byte[1024];
            int readLen;
            while((readLen = bis.read(data)) != -1){
                bos.write(data,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);
            }
        }
    }
}
3.ObjectOutputStream
package com.yang.outputstream_;

import org.junit.Test;

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

public class TestObjectOutputStream {

    @Test
    public void test(){
        ObjectOutputStream oos = null;

        try {
            // 保存序列化的文件有固定的格式.dat
            oos = new ObjectOutputStream(new FileOutputStream("e:\\io\\obj.dat"));
            oos.writeInt(1000); // int ==> Integer
            oos.writeFloat(1.1f); // float ==> Float
            oos.writeChar('Y'); // char ==> Char
            // 因为基本数据类型的包装类和String类都直接或间接的实现了Serializable接口,所以可以实现序列化
            oos.writeUTF("java");
            oos.writeObject(new Dog("大黑",5)); // 序列化对象,需要对应的类实现Serializable接口

        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            if (oos != null){
                try {
                    oos.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }
}

class Dog implements Serializable接口,可以实现序列化 { // 该类实现了Serializable接口,可以实现序列化
    String name;
    int age;

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

(三)Reader

1.FileReader

常用API:

int read() // 读取单个字符,效率低
int read(char cbuf[]) // 读取一个字符数组

测试:

package com.yang.reader_;

import org.junit.Test;

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

public class FileReader_ {

    @Test
    public void test(){
        FileReader fr = null;
        try {
            fr = new FileReader("e:\\io\\reader.txt");
            int data = 0;
            // read() 读取单个字符,当返回-1时表示读取到文件末尾
            while ((data = fr.read()) != -1){
                System.out.print((char) data);
            }

        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            if (fr != null){
                try {
                    fr.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }

    @Test
    public void test02(){
        FileReader fr = null;
        try {
            fr = new FileReader("e:\\io\\reader.txt");
            int len = 0;
            char[] data = new char[8];

            // read(char cbuf[]) 读取一个字符数组,返回的是读取到的字符长度
            // 当返回-1时表示读取到文件末尾
            while ((len = fr.read(data)) != -1){
                System.out.print(new String(data,0,len));
            }

        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            if (fr != null){
                try {
                    fr.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }
}
2.BufferedReader

字符输入流拓展API:

String readLine() // 按行读取文件

测试:

package com.yang.reader_;

import org.junit.Test;

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

public class TestBufferedReader {

    @Test
    public void test(){
        BufferedReader br = null;
        try {
            br = new BufferedReader(new FileReader("e:\\io\\reader.txt"));

            String len;
            // readLine 方法按行读取文件,效率更高,当读取到文件末尾时返回null
            while ((len = br.readLine()) != null){
                System.out.println(len);
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            if (br != null){
                try {
                    br.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }
}
3.InputStreamReader
public InputStreamReader(InputStream in, Charset cs) // 该构造器可以指定特定的编码读取文件

测试:

package com.yang.reader_;

import org.junit.Test;

import java.io.*;

public class TestInputStreamReader {

    @Test
    public void test(){
        BufferedReader br = null;
        try {
            // FileReader 默认使用的是utf-8的编码格式读取文件,当文件编码不是utf-8时,可能出现乱码
            br = new BufferedReader(new FileReader("e:\\io\\isr.txt"));
            System.out.println(br.readLine());
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            if (br != null){
                try {
                    br.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }

    @Test
    public void test02(){
        // 使用InputStreamReader指定读取文件时的编码格式
        // 使用指定编码读取文件(当指定和文件的编码格式相同时,解决乱码问题)
        // 可以将一个字节流转换为一个字符流
        BufferedReader br = null;
        try {
            // InputStreamReader(InputStream in, Charset cs)
            br = new BufferedReader(new InputStreamReader(new FileInputStream("e:\\io\\isr.txt"),"gbk"));
            System.out.println(br.readLine());
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            if (br != null){
                try {
                    br.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }
}

(四)Writer

1.FileWriter

常用API:

void write(int c) // 写入单个字符
void write(char cbuf[]) // 写入一个字符数组(写入多个字符)
void write(char cbuf[], int off, int len) // 写入指定长度的字符数组
void write(String str) // 写入一个字符串
void write(String str, int off, int len) // 从一个字符数组中截取字符并读取到文件中

测试:

package com.yang.writer_;

import org.junit.Test;

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

public class FileWriter_ {

    @Test
    public void test(){

        FileWriter fw = null;

        try {
            fw = new FileWriter("e:\\io\\writer.txt");
            // write(int c) 写入单个字符
            // fw.write('Y');
            // fw.write('Y');

            // write(char cbuf[]) 写入一个字符数组(写入多个字符)
            // String data = new String("hello,world");
            // fw.write(data.toCharArray()); // toCharArray方法将一个字符串转为字符数组

            // write(String str) 写入一个字符串
            fw.write("你好呀!");
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            try {
                if (fw != null){
                    fw.close(); // 或者使用flush(刷新)
                }
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }

    @Test
    public void test02(){

        FileWriter fw = null;

        try {
            // FileWriter(String fileName, boolean append) 设置为true时表示为追加
            fw = new FileWriter("e:\\io\\writer.txt",true);

            // char[] data = {'j','a','v','a','h','e','l','l','o'};
            // write(String str, int off, int len) 从一个字符数组中截取字符并读取到文件中
            // fw.write(data,4,5);

            // write(String str, int off, int len) 从一个字符串中截取字符并读取到文件中
            fw.write("hello,world",6,5);
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            try {
                if (fw != null){
                    fw.close(); // 或者使用flush(刷新)
                }
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }
}
2.BufferedWriter

字符输出流拓展API:

void newLine() // 插入一个换行符

测试:

package com.yang.writer_;

import org.junit.Test;

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

public class TestBufferedWriter {

    @Test
    public void test(){
        BufferedWriter bw = null;

        try {
            bw = new BufferedWriter(new FileWriter("e:\\io\\aaa.txt"));
            bw.write("hello1");
            bw.newLine(); // 插入一个换行符
            bw.write("hello2");
            bw.newLine();
            bw.write("hello3");
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            if (bw != null){
                try {
                    bw.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }
}
文件拷贝
package com.yang.writer_;

import org.junit.Test;

import java.io.*;

public class FileCopy {

    @Test
    public void test(){

        BufferedReader br = null;
        BufferedWriter bw = null;

        try {
            br = new BufferedReader(new FileReader("e:\\io\\CopyFile.java"));
            bw = new BufferedWriter(new FileWriter("e:\\io\\CopyFile02.java"));

            String data;
            while((data = br.readLine()) != null){ // 按行读取
                bw.write(data); // 以字符的形式写入
                bw.newLine(); // 换行
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            try {
                if (br != null) {
                    br.close();
                }
                if (bw != null){
                    bw.close();
                }
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }
}
3.OutputStreamWriter
public OutputStreamWriter(OutputStream out, String charsetName) // 在写入数据到文件时,指定该文件的编码格式

测试:

package com.yang.writer_;

import org.junit.Test;

import java.io.*;

public class TestOutputStreamWriter {

    @Test
    public void test(){
        // 使用OutputStreamWriter在写入数据到文件时指定编码格式
        OutputStreamWriter osw = null;
        try {
            osw = new OutputStreamWriter(new FileOutputStream("e:\\io\\osw.txt"),"gbk");
            osw.write("hello 玉林!!!");
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            if (osw != null){
                try {
                    osw.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }
}

三、Properties

  • 该类用于读写配置文件
  • 有严格的格式:key=value(键值对)
  • 键值对不需要空格,值不需要引号标注,默认的类型为String类型

常用API:

void load(InputStream inStream) // 传入一个流对象,用来加载配置文件
String getProperty(String key) // 根据key获取value
Object setProperty(String key, String value) // 如果key存在,则修改value,如果不存在,则设置一个新的key和value
void store(Writer writer, String comments) // 可以以字符流的方式写入数据,comments为生成的注释信息
void store(OutputStream out, String comments) // 可以以字节流的方式写入数据,comments为生成的注释信息

测试:

package com.yang.properties;

import org.junit.Test;

import java.io.*;
import java.util.Properties;

public class TestProperties {

    /**
     * 使用传统方式读取配置文件
     */
    @Test
    public void test(){
        BufferedReader br = null;
        try {
            br = new BufferedReader(new FileReader("src\\db.properties"));
            String data = "";
            while((data = br.readLine()) != null) {
                String[] dataArr = data.split("=");
                System.out.println("key=" + dataArr[0] + " value=" + dataArr[1]);
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            if (br != null){
                try {
                    br.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }

    /**
     * 使用Properties类读取配置文件
     */
    @Test
    public void test02(){
        Properties properties = new Properties();
        // 加载配置文件
        try {
            properties.load(new FileReader("src\\db.properties"));
            // 输出所有信息到控制台
            properties.list(System.out);
            // getProperty根据key获取value
            String user = properties.getProperty("user");
            String password = properties.getProperty("password");
            System.out.println("用户名:" + user);
            System.out.println("密码:" + password);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 使用Properties类创建和修改配置文件
     */
    @Test
    public void test03(){
        Properties properties = new Properties();
        // setProperty方法,当该键值对不存在时,则添加到配置文件中,如果存在,则修改值
        properties.setProperty("charset","utf8"); // 指定字符编码
        properties.setProperty("user","张三");
        properties.setProperty("password","root");

        try {
            // 使用字节流的方式保存中文数据到配置文件中时,是中文类型对应的unicode值
            // properties.store(new FileOutputStream("src\\db02.properties"),null);
            // 第二个参数传入null表示该文件不生成注释信息
            properties.store(new FileWriter("src\\db02.properties"),null);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}
  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值