文件操作---File丶FileInputStream丶BufferedInputStream丶InputStreamReader丶FileReader丶BufferedReader

版权声明:如需转载或引用请声明原文网址 https://blog.csdn.net/u013087359/article/details/81256277

一.File

1.路径

  • 绝对路径:带盘符的完整路径
  • 相对路径:相对于某个文件或目录的路径(Eclipse中相对于项目的根目录)
  • Windows下目录分隔符可以是\/,Linux下只能是/ ,建议统一使用/File.separator
  • Windows路径不区分大小写,Linux下路径区分大小写

2.构造方法

  • File(String pathname)
    • 使用文件或目录路径创建File对象
  • File(String parent, String child)
    • 根据父目录路径和子目录或子文件路径创建File对象,parentchild会进行字符串拼接
  • File(File parent, String child)
    • 作用同上,父目录路径换成了File对象

3.成员方法

  • boolean createNewFile()

    • 创建一个新文件,创建成功返回true,创建失败或者文件已存在则返回false
    • 文件的每层父目录必须都存在,否则会抛出java.io.IOException: 系统找不到指定的路径
  • boolean mkdir()

    • 创建一个新目录,创建成功返回true,创建失败或者目录已存在或者父目录不存在则返回false
  • boolean mkdirs()

    • 创建新目录,所有不存在的父目录也会被一起创建出来,创建成功返回true,创建失败或者目录已存在则返回false
  • boolean delete()

    • 删除文件或目录,删除成功返回true, 路径不存在或者目录下存在子文件或目录都会返回false
    • 文件或目录会被直接删除掉,不会放到回收站
  • boolean renameTo(File dest)

    • 当目标路径与原路径是同一父目录时,则执行的是改名操作
    • 当目标路径与原路径不是同一父目录时,则执行的是剪切并改名
    • 如果目标路径的父目录不存在,则返回false
    • 即使原目录下有子文件或目录,也可以成功被改名和剪切
    • 重命名操作无法将一个文件从一个文件系统移动到另一个文件系统,所以谨慎使用,可以用 apache的common-io包实现相同的功能
  • boolean isFile()

    • 判断是否文件类型
  • boolean isDirectory()

    • 判断是否目录类型
  • boolean isAbsolute()

    • 判断创建对象时传入的路径是否绝对路径
  • boolean isHidden()

    • 判断是否隐藏
  • boolean canRead()

    • 判断是否可读
  • boolean canWrite()

    • 判断是否可读
  • boolean exists()

    • 判断是否存在
  • boolean setReadable(boolean readable)

    • 设置只读状态,Windows下设置不可读会返回false,默认全部文件都是可读的
  • boolean setWritable(boolean writable)

    • 设置可写状态
  • boolean setLastModified(long time)

    • 设置文件最后一次修改的时间,单位毫秒
  • long length()

    • 获取文件大小,单位:字节
  • long lastModified()

    • 获取文件最后被修改的时间,单位:毫秒
  • String getAbsolutePath()

    • 获取绝对路径,无论创建File对象时传入的是相对路径还是绝对路径,都会返回返回绝对路径
  • String getPath()

    • 获取创建File对象时传入的路径
  • String getName()

    • 获取文件名(带后缀)或目录名
  • String getParent()

    • 返回父目录路径
  • String[] list(FilenameFilter filter)

    • 获取当前目录下所有的子文件名(带后缀)或子目录名
    • 过滤器用于过滤文件或目录名,匿名实现过滤器并重写方法,不填写参数时则不过滤
  • File[] listFiles(FileFilter filter)

    • 获取当前目录下所有子文件或子目录File对象
    • 过滤器用于过滤文件或目录名,匿名实现过滤器并重写方法,不填写参数时则不过滤

二.FileInputStream&FileOutputStream

1.构造方法

  • FileInputStream(String name|File file)

    • 根据文件路径或者File对象创建字节输入流
    • 如果文件不存在则抛出java.io.FileNotFoundException
  • FileOutputStream(String name|File file, boolean append)

    • 根据文件路径或者File对象创建字节输出流
    • 如果文件不存在,则会自动创建,但父目录不存在时则会报错
    • 当第二个参数为false或不填写时,则会覆盖原文件内容,参数为true时,则在文件末尾追究内容

2.成员方法

  • int read(byte[] b)

    • 从文件输入流中读取数据进byte数组中
    • 返回的是实际读取的字节数,返回值为-1表示已读取完毕
  • void write(byte[] b, int off, int len)

    • 将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此文件输出流
  • void close()

    • 关闭流,释放资源

3.复制文件例子

//创建字节输入流
FileInputStream fis=new FileInputStream("a.txt");
//创建字节输出流
FileOutputStream fos=new FileOutputStream("copy_a.txt");
//创建字节数组,用于临时存放读入的字节,效率比每次读取单个字节高(内存操作比IO操作快很多)
byte[] bs=new byte[1024*8];
//实际读入的字节数
int len;
//循环把数据读入到字节数组中,直到读取完毕
while((len=fis.read(bs))!=-1){
    //把字节数组写入到文件中
    //最后一次读取可能填满整个字节数组,所以需要把实际读取的写入文件
    fos.write(bs, 0, len);
}

//关闭流,释放资源
fis.close();
fos.close();    

三.BufferedInputStream&BufferedOutputStream

1.概述

  • BufferedInputStream是对FileInputStream的包装,自带缓冲区,自动根据缓冲区字节数判断进行文件读入缓冲区,而read()读取的是缓冲区,并非读取文件

  • FileInputStream可能会出现阻塞,而BufferedInputStream不会阻塞,效率稍高

  • BufferedOutputStream是对FileOutputStream的包装,write()是写入缓冲区,当缓冲区满了自动flush()把内容刷新写进文件中

  • BufferedInputStream与BufferedOutputStream的缓冲区不是同一个缓冲区,各自管理自己的

2.构造方法

  • BufferedInputStream(InputStream in, int size)

    • 根据字节输入流创建缓冲字节输入流
    • 第二个参数size表示缓冲区的大小,不填写时默认1024*8
  • BufferedOutputStream(OutputStream out, int size)

    • 根据字节输出流创建缓冲字节输出流
    • 第二个参数size表示缓冲区的大小,不填写时默认1024*8

3.成员方法

  • 同FileInputStream&FileOutputStream

4.案例

  • 复制任何类型的文件优先选择此方式
//创建字节输入流
FileInputStream fis=new FileInputStream("a.txt");
//创建字节输出流
FileOutputStream fos=new FileOutputStream("copy_a.txt");

//创建缓冲流
BufferedInputStream bis=new BufferedInputStream(fis);
BufferedOutputStream bos=new BufferedOutputStream(fos);

byte[] bs=new byte[1024];
int len;
//从BufferedInputStream缓冲区读取数据进字节数组中,当缓冲区没有数据时,会自动读取文件填充缓冲区
while((len=bis.read(bs))!=-1){
    //写入数据到BufferedOutputStream缓冲区,当缓冲区满时,会自动写入到文件中
    bos.write(bs, 0, len);
}

//关闭缓冲流,释放资源,字节流也会随着被关闭
bis.close();
//输出缓冲流关闭前会调用flush()把数据刷到文件中
bos.close();

四.捕捉异常并关闭IO流

1.普通方式

//声明流
FileInputStream fis = null;
FileOutputStream fos = null;

try {
    fis = new FileInputStream("a.txt");
    fos = new FileOutputStream("copy_a.txt");
    byte[] bs = new byte[1024 * 8];
    int len;
    while ((len = fis.read(bs)) != -1) {
        fos.write(bs, 0, len);
    }
} catch (Exception e) {
    e.printStackTrace();
} finally {     
    try {
        // 关闭输入流
        if (fis != null) {
            fis.close();
        }
    } catch (IOException e) {
        e.printStackTrace();
    }

    try {
        // 关闭输出流
        if (fos != null) {
            fos.close();
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}

2.jdk1.7+方式

jdk1.7提供了try(对象创建代码区){普通代码区} 方式自动调用AutoCloseable接口的close()方法。而字节流顶层类InputStream和OutStream都实现了AutoCloseable接口,并在重写方法close() 中添加了关闭流等操作,所以达到了自动关闭流效果。

    try(
        //实现了AutoCloseable接口的类创建对象放 在try()中
        FileInputStream fis = new FileInputStream("a.txt");
        FileOutputStream fos = new FileOutputStream("copy_a.txt");
    ){
        //在try{}中可以访问try()中的对象
        byte[] bs = new byte[1024 * 8];
        int len;
        while ((len = fis.read(bs)) != -1) {
            fos.write(bs, 0, len);
        }
    }catch (Exception e) {
        e.printStackTrace();
    }

    //不用手动关闭流,会自动关闭

五.InputStreamReader&OutputStreamWriter

1.概述

  • 是字节流转换为字符流的桥梁
  • 可以指定转换编码或使用系统默认编码(UTF-8字符占用3个字节,GBK字符占用2个字节)

2.构造方法

  • InputStreamReader(InputStream in, String charsetName)

    • 根据字节输入流创建InputStreamReader对象
    • charsetName可指定编码格式,如果为空则使用系统默认的编码,读取的文件编码与流编码要一致,否则可能出现乱码
  • OutputStreamWriter(OutputStream out, String charsetName)

    • 根据字节输出流创建OutputStreamWriter对象
    • charsetName可指定编码格式,如果为空则使用系统默认的编码,写入的文件编码与流编码要一致,否则可能出现乱码

3.成员方法

  • int read()

    • 读取单个字符,如果读到流的末尾,则返回-1
    • 返回的是Unicode码值,需要用char强转后才得到真正的字符
  • int read(char[] cbuf)

    • 读取多个字符进数组中,如果读到流的末尾,则返回-1
    • 返回值是实际读取的字符数
  • void close()

    • 关闭流并释放关联的资源
  • void write(int c)

    • 写入单个字符
  • void write(String str)

    • 把字符串写入文件中

4.例子

    //使用UTF-8编码把a.txt文件字节流转换为字符流
    InputStreamReader isr=new InputStreamReader(new FileInputStream("a.txt"),"UTF-8");
    //读取单个字符
    int n=isr.read();
    //关闭流
    isr.close();
    //把码值转换为字符
    char c=(char)n;

    if(c=='你'){
        //使用GBK编码把字符流转换为字节流再追加在b.txt文件中
        OutputStreamWriter osw=new OutputStreamWriter(new FileOutputStream("b.txt",true),"GBK");
        //写入字符串
        osw.write("你好");
        //关闭流
        osw.close();
    }

六.FileReader&FileWriter

1.概述

  • FileReader&FileWriter是InputStreamReader&OutputStreamWriter的子类,已经搭建好桥梁,可直接操作文件
  • 不可指定编码格式,需要编码要用InputStreamReader&OutputStreamWriter

2.构造方法

  • FileReader(String fileName)

    • 根据文件名创建FileReader对象
  • FileWriter(String fileName, boolean append)

    • 根据文件名创建FileWriter对象
    • 如果文件不存在,则会自动创建,但父目录不存在时则会报错
    • 当第二个参数为false或不填写时,则会覆盖原文件内容,参数为true时,则在文件末尾追究内容

3.成员方法

  • 同InputStreamReader&OutputStreamWriter

4.例子

    //创建a.txt的字符输入流
    FileReader fr=new FileReader("a.txt");
    char[] cs=new char[10];
    //读取多个字符进数组中
    fr.read(cs);
    //关闭流
    fr.close();
    if(cs.length>1){
        //创建b.txt的字符输出流,并设置写入格式为追加内容
        FileWriter fw=new FileWriter("b.txt",true);
        //写入内容
        fw.write("你好");
        //关闭流
        fw.close();
    }

七.BufferedReader&BufferedWriter

1.概述

  • 跟BufferedInputStream&BufferedOutputStream作用一样,一个是操作字节流,一个操作的是字符流

2.构造方法

  • BufferedReader(Reader in, int sz)
  • 根据字符输入流创建缓冲字符输入流

    • 第二个参数size表示缓冲区的大小,不填写时默认1024*8
  • BufferedWriter(Writer out, int sz)

    • 根据字符输出流创建缓冲字符输出流
    • 第二个参数size表示缓冲区的大小,不填写时默认1024*8

3.特有成员方法

  • String readLine()

    • 读取一行文本 ,到达流的末尾返回null
  • void newLine()

    • 写入一个换行符

4.例子

    //根据c.txt的字符输入流创建缓冲字符输入流
    BufferedReader br=new BufferedReader(new FileReader("c.txt"));
    //根据d.txt的字符输出流创建缓冲字符输出流
    BufferedWriter bw=new BufferedWriter(new FileWriter("d.txt"));
    String line;
    //循环读取每一行
    while((line=br.readLine())!=null){
        //把内容写入到文件中
        bw.write(line);
        //换行
        bw.newLine();
    }
    //关闭流并释放关联的资源
    br.close();
    bw.close();

八.LineNumberReader

1.概述

  • LineNumberReader是对BufferedReader扩展了行号功能
  • 只有LineNumberReader类,没有LineNumberWriter类

2.构造方法

  • 同BufferedReader

3.特有成员方法

-int getLineNumber()
- 获取当前行号

  • void setLineNumber(int lineNumber)
    • 设置当前行号
    • 行号只是一个标志的数字,并没有筛选行的功能,无论行号多少,都不会影响读取的内容

4.例子

    LineNumberReader lnr=new LineNumberReader(new FileReader("c.txt"));
    String line;
    //设置当前行号为100(行号只是一个标志的数字,并没有筛选行的功能,无论行号多少,都不会影响读取的内容)
    lnr.setLineNumber(100);
    //每执行一次readLine()行号都会+1
    while((line=lnr.readLine())!=null){
        //获取行号
        System.out.println(lnr.getLineNumber()+":"+line);
    }

九.SequenceInputStream

1.概述

  • 对多个字节输入流放进序列组合中,逐一执行相同的操作
  • 当前面的流读取完毕,会自动切换到下一个流中

2.构造方法

  • SequenceInputStream(InputStream s1, InputStream s2)

    • 合并两个输入字节流
  • SequenceInputStream(Enumeration<? extends InputStream> e)

    • 使用枚举器合并多个输入字节流

3.例子

FileInputStream fis1=new FileInputStream("a1.txt");
        FileInputStream fis2=new FileInputStream("a2.txt");

        //把两个输入字节流传递进序列字符流中
        SequenceInputStream sis=new SequenceInputStream(fis1,fis2);

        //把a1.txt和a2.txt文件的内容合并到a3.txt中
        FileOutputStream fos=new FileOutputStream("a3.txt");        
        int len;
        byte[] arr=new byte[1024];
        while((len=sis.read(arr))!=-1){
            fos.write(arr, 0, len);
        }

        //关闭序列输入流和其相关的流
        sis.close();
        fos.close();
        //创建多个输入字节流,分别关联不同的文件
        FileInputStream fis1=new FileInputStream("b1.txt");
        FileInputStream fis2=new FileInputStream("b2.txt");
        FileInputStream fis3=new FileInputStream("b3.txt");
        FileInputStream fis4=new FileInputStream("b4.txt");

        //创建Vector集合
        Vector<FileInputStream> list=new Vector<FileInputStream>();

        //把多个输入字节流添加进集合中
        list.add(fis1);
        list.add(fis2);
        list.add(fis3);
        list.add(fis4);

        //获取Vector集合的枚举器
        Enumeration<FileInputStream> en=list.elements();
        //把枚举器传递给序列字节流中
        SequenceInputStream sis=new SequenceInputStream(en);

        FileOutputStream fos=new FileOutputStream("b5.txt");

        int len;
        byte[] arr=new byte[1024];
        while((len=sis.read(arr))!=-1){
            fos.write(arr, 0, len);
        }

        sis.close();
        fos.close();

十.ByteArrayOutputStream

1.概述

  • 字节数组输出流,存在于内存中,是一个可变长度的缓冲区

2.构造方法

  • ByteArrayOutputStream(int size)
    • 可指定缓冲区大小,不填写参数时使用默认的大小

3.成员方法

  • void write(byte[] b, int off, int len)

    • 把字节数组的指定区间元素写入到内存输出流的缓冲区中
  • writeTo(OutputStream out)

    • 把内存输出流缓冲区的内容写入到文件中
  • String toString(String charsetName)

    • 把缓冲区内容使用指定编码转换成字符串 ,不填写参数时使用默认的编码

4.例子

    FileInputStream fis=new FileInputStream("a.txt");

    //创建内存输出流
    ByteArrayOutputStream bos=new ByteArrayOutputStream();

    byte[] arr=new byte[1024];
    int len;
    while((len=fis.read(arr))!=-1){
        //读取a.txt的内容进内存输出流的缓冲区中
        bos.write(arr,0,len);
    }

    fis.close();

    //把缓冲区的内容转换为字符串
    System.out.println(bos.toString());

    //字节输出流
    FileOutputStream fos=new FileOutputStream("to_a.txt");

    //根据字节输出流把缓冲区内容写入的到文件中
    bos.writeTo(fos);
    fos.close();

    //关闭内存输出流无效,因为它是存在内存中的,并没有与文件有直接关系,所以关不关闭都没有影响
    bos.close();

十一.DataInputStream&DataOutputStream

    FileOutputStream fos=new FileOutputStream("f.txt");
    //创建数据输入流
    DataOutputStream dos=new DataOutputStream(fos);
    //写入整数
    dos.writeInt(987);
    //写入小数
    dos.writeDouble(2.34);
    //写入UTF-8编码格式写入字符串
    dos.writeUTF("你好");
    //关闭流和其相关的资源
    dos.close();

    FileInputStream fis=new FileInputStream("f.txt");
    //创建数据输出流
    DataInputStream dis=new DataInputStream(fis);
    //读取整型
    int num1=dis.readInt();
    //读取小数
    double num2=dis.readDouble();
    //读取UTF字符串
    String str=dis.readUTF();

    //关闭流和其相关的资源
    dis.close();

十二.RandomAccessFile

1.概述

  • 整合了输入流和输出流

2.构造方法

  • RandomAccessFile(File file, String mode)

    • 根据File对象创建RandomAccessFile对象
    • mode表示打开文件模式,r 表示只读,rw 表示读写,还有rwsrwd
  • RandomAccessFile(String name, String mode)

    • 根据文件路径创建RandomAccessFile对象

3.成员方法

  • int read()
  • int read(byte[] b)
  • boolean readBoolean()
  • char readChar()
  • double readDouble()
  • int readInt()
  • long readLong()
  • short readShort()
  • void write(int b)
  • void write(byte[] b)
  • void write(byte[] b, int off, int len)
  • void writeBoolean(boolean v)
  • void writeChar(int v)
  • void writeDouble(double v)
  • void writeFloat(float v)
  • void writeInt(int v)
  • void writeLong(long v)
  • void writeShort(int v)
  • void writeChars(String s)

  • String readLine()

    • 读取一行内容
    • new String( raf.readLine().getBytes("ISO-8859-1"),"UTF-8") 解决中文乱码
  • long length()

    • 获取文件大小,单位:字节
  • void seek(long pos)

    • 设置读写位置 (以字节数为偏移量)
  • int skipBytes(int n)

    • 从当前位置跳过指定字节,当n为负数,则不跳过
  • long getFilePointer()

    • 获取读写位置 (以字节数为偏移量)

十三.ObjectInputStream&ObjectOutputStream

1.概述

  • 对象输出输入流用于序列化引用类型和基本类型的数据
  • 序列化的类需要实现Serializable接口

2.构造方法

  • ObjectInputStream(InputStream in)
  • ObjectOutputStream(OutputStream out)

3.成员方法

  • void writeInt(int val)
  • void writeObject(Object obj)
  • int readInt()
  • Object readObject()

4.例子

//序列化的类需要实现Serializable接口
public class Person implements Serializable{
    //序列化的版本ID,用于区分序列化时的类和反序列化时的类是否发生更改
    //实现Serializable接口也可以不声明ID,会自动编号
    private static final long serialVersionUID = 1L;
}
    Person p1=new Person("张三",23);
    Person p2=new Person("李四",24);
    Person p3=new Person("王五",25);

    ArrayList<Person> list=new ArrayList<>();
    list.add(p1);
    list.add(p2);
    list.add(p3);

    //创建对象输出流
    ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("object.txt"));

    //写出整型数据
    oos.writeInt(1);
    //写出对象
    oos.writeObject(p1);
    //写出集合
    oos.writeObject(list);

    //关闭流和其相关的资源
    oos.close();

    //创建对象输入流
    ObjectInputStream ois=new ObjectInputStream(new FileInputStream("object.txt"));

    //写入顺序和读取顺序是一致的

    //读取整型
    int num=ois.readInt();
    //读取对象
    Person p=(Person)ois.readObject();
    //读取集合
    ArrayList<Person> pList=(ArrayList<Person>)ois.readObject();

    //关闭流和其相关的资源
    ois.close();

    System.out.println(num);
    System.out.println(p);
    System.out.println(pList);

十四.Properties

1.概述

  • Properties是属性键值对集合,键和值都是字符串,是Hashtable的子类,无序,不可重复
  • Properties可以操作.properties属性文件

2.构造方法

  • Properties()
    • 无参构造

3.成员方法

  • String getProperty(String key, String defaultValue)

    • 根据键获取值
    • defaultValue参数当键不存在时,则返回默认的defaultValue,当不填写该参数时,返回null
  • Object setProperty(String key, String value)

    • 添加或修改键值
  • Enumeration<?> propertyNames()

    • 获取所有的键
  • void load(Reader reader)

    • 加载文件中的内容进属性集合中
  • void store(OutputStream out, String comments)

    • 把属性集合写进文件中
    • comments是注释说明,中文可能出现编码不对,注释最好手动在文件中添加

4.例子

#学生配置信息
#properties文件注释以#开头
#格式:  键=值
age=23
name=张三
    //创建属性集合
    Properties prop=new Properties();
    //添加2个属性
    prop.setProperty("name", "张三");
    prop.setProperty("age", "23");

    //把属性集合写入到properties文件中
    prop.store(new FileWriter("config.properties"), null);

    //把config.properties内容读入到属性集合中
    prop.load(new FileReader("config.properties"));

    //获取属性集合的所有键
    Enumeration<String> en=(Enumeration<String>) prop.propertyNames();

    //遍历所有键
    while(en.hasMoreElements()){
        //获取当前枚举的键
        String key=en.nextElement();
        //根据键获取值
        String value=prop.getProperty(key);
        System.out.println(key+"="+value);
    }

猜你喜欢

转载自blog.csdn.net/u013087359/article/details/81256277
今日推荐