Java读写文件

​ java读写文件的方法挺多的,在初学java的时候更是傻傻分不清,在搜集各路大神的资料后,我总结了一个较为完善的版本。

一、文件IO图

Alt dd

二、相关的类和流

  1. File类

    • File类封装了对用户机器的文件系统进行操作的功能。例如,可以用File类获得文件上次修改的时间移动,或者对文件进行删除、重命名。
    • File类的主要方法有:getName(),getCanonicalFile(),lastModified(),isDerector(),isFile(),getPath()
    • ②File类与FileInputStream类的区别:
    • 流类关注的是文件内容,而File类关注的是文件在磁盘上的存储
    • File不属于文件流,只能代表一个文件或是目录的路径名而已。
    • 如果处理文件或者目录名,就应该使用File对象,而不是字符串。例如,File类的equals方法知道一些文件系统对大小写是敏感的,目录尾的“/”字符无关紧要。
    • 自己的领会: FileInputStream类或者FileReader类的构造函数有多个,其中典型的两个分别为:一个使用File对象为参数;而另一个使用表示路径的String对象作为参数;自己以前一直觉得直接用了String指定路径就可以了,一直不明白为什么很多人都先构造一个File对象,现在终于明白了,“如果处理文件或者目录名,就应该使用File对象,而不是字符串。”!
  2. FileInputStream类

    • ①FileInputStream类介绍:

    • 字节为单位(非unicode)的流处理。字节序列即:二进制数据。与编码无关,不存在乱码问题。

    • FileInputStream类的主要方法有: Read()read(byte[] b)read(byte[],int off,int len),available();

    • ②FileInputStream类与FileReader类的区别:

      两个类的构造函数的形式和参数都是相同的,参数为File对象或者表示路径的String,它们到底有何区别呢?

      FileInputStream以字节流方式读取

      FileReader:把文件转换为字符流读

      InputStream提供的是字节流的读取,而非文本读取,这是和Reader类的根别。用Reader读取出来的是char数组或者String ,使用InputStream读取出来的是byte数组

      Reader类及其子类提供的字符流的读取char(16位,unicode编码)inputStream及其子类提供字节流的读取byte(8位),所以FileReader类是将文件按字符流的方式读取,FileInputStream则按字节流的方式读取文件;InputStreamReader可以将读如stream转换成字符流方式是reader和stream之间的桥梁

      最初Java是不支持对文本文件的处理的,为了弥补这个缺憾而引入了Reader和Writer两个类。

      FileInputStream类以二进制输入/输出,I/O速度快且效率搞,但是它的read()方法读到的是一个字节(二进制数据),很不利于人们阅读。

      而FileReader类弥补了这个缺陷,可以以文本格式输入/输出,非常方便;比如可以使用while((ch = filereader.read())!=-1 )循环来读取文件;可以使用BufferedReader的readLine()方法一行一行的读取文本

      当我们读写文本文件的时候,采用Reader是非常方便的,比如FileReader, InputStreamReader和BufferedReader。其中最重要的类是InputStreamReader,它是字节转换为字符的桥梁。 你可以在构造器重指定编码的方式,如果不指定的话将采用底层操作系统的默认编码方式,例如GBK等。

      FileReader与InputStreamReader涉及编码转换(指定编码方式或者采用os默认编码)可能在不同的平台上出现乱码现象!而FileInputStream以二进制方式处理不会出现乱码现象.

      自己的领会:

      如果处理纯文本文件,建议使用FileReader,因为更方便,也更适合阅读;但是要注意编码问题!

      其他情况(处理非纯文本文件),FileInputStream是唯一的选择;FileInputStream是进Socket通讯时会用到很多,如将文件流是Stream的方式传向服务器!

  3. FileReader类

    InputStreamReader类的子类,所有方法(read()等)都从父类InputStreamReader中继承而来;

    ② 与InputStreamReader类的区别:

    参见上面的区别;

    自己的领会:

    该类与它的父类InputStreamReader的主要不同在于构造函数,主要区别也就在于构造函数!从InputStreamReader的构造函数中看到,参数为InputStream和编码方式,可以看出,当要指定编码方式时,必须使用InputStreamReader类;而FileReader构造函数的参数与FileInputStream同,为File对象或表示path的String,可以看出,当要根据File对象或者String读取一个文件时,用FileReader;我想FileReader子类的作用也就在于这个小分工吧。

一般用法:

FileReader fr = new FileReader(“ming.txt”);

   char[] buffer = new char[1024];

   int ch = 0;

  while((ch = fr.read())!=-1 )

  {

   System.out.print((char)ch);

  }

  1. InputStreamReader类

    以文本格式输入/输出,可以指定编码格式;

    主要方法: getEncoding(),read();

    一般用法:

    InputStreamReader isr = new InputStreamReader(new FileInputStream(“ming.txt”));

      while((ch = isr.read())!=-1)

      {

       System.out.print((char)ch);

      }

  2. BufferedReader类

    BufferedReader 由Reader类扩展而来,提供通用的缓冲方式文本读取,而且提供了很实用的readLine,读取分行文本很适合,BufferedReader是针对Reader的,不直接针对文件,也不是只针对文件读取。

    一般用法:

    BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(“ming.txt”)));

       String data = null;

       while((data = br.readLine())!=null)

       {

        System.out.println(data);

       }

  3. 总结以上内容,得出比较好的规范用法:

    File file = new File (“hello.txt”);

    FileInputStream in=new FileInputStream(file);

    File file = new File (“hello.txt”);

    FileInputStream in=new FileInputStream(file);

    InputStreamReader inReader=new InputStreamReader(in);

    BufferedReader bufReader=new BufferedReader(inReader);

    File file = new File (“hello.txt”);

    FileReader fileReader=new FileReader(file);

    BufferedReader bufReader=new BufferedReader(fileReader);

  4. FileWriter类:

    构造方法:FileWriter fw = new FileWriter(String fileName);//创建字符输出流类对象和已存在的文件相关联。文件不存在的话,并创建。

    ​ 如:FileWriter fw = new FileWriter(“C:\demo.txt”);

    ​ FileWriter fw = new FileWriter(String fileName,boolean append);//创建字符输出流类对象和已存在的文件相关联,并设置该该流对文件的操作是否为续写。

    ​ 如:FileWriter fw = new FileWriter(“C:\demo.txt”,ture); //表示在fw对文件再次写入时,会在该文件的结尾续写,并不会覆盖掉。

    主要方法: void write(String str) //写入字符串。当执行完此方法后,字符数据还并没有写入到目的文件中去。此时字符数据会保存在缓冲区中。

    ​ 此时在使用刷新方法就可以使数据保存到目的文件中去。

    ​ viod flush() //刷新该流中的缓冲。将缓冲区中的字符数据保存到目的文件中去。

    ​ viod close() //关闭此流。在关闭前会先刷新此流的缓冲区。在关闭后,再写入或者刷新的话,会抛IOException异常

    package filewriter;

import java.io.FileWriter;

import java.io.IOException;

public class Filewriter {

​ private static final String LINE_SEPARATOR = System.getProperty(“line.separator”);

/** 

​ *

​ * @param args

​ * @throws IOException

​ */

​ public static void main(String[] args) throws IOException {

​ /**

​ * 创建一个可以往文件中写入字符数据的字符流输出流对象

​ * 创建时必须明确文件的目的地

​ * 如果文件不存在,这回自动创建。如果文件存在,则会覆盖。

​ * 当路径错误时会抛异常

​ *

​ * 当在创建时加入true参数,回实现对文件的续写。

​ */

​ FileWriter fw = new FileWriter(“C:\demo1.txt”,false);

​ /**

​ * 调用该对象的write方法,向文件写入字符。

​ *

​ * 其实写入到了临时存储缓冲区中

​ */

// fw.write(“hello \r\nworld!”);//windows中的换行为\r\n unix下为\r。

​ fw.write(“aello”+LINE_SEPARATOR+”world!”); fw.write(“hahaha”);

​ /**

​ * 进行刷新,将字符写到目的地中。

​ */

// fw.flush();

​ /**

​ * 关闭流,关闭资源。在关闭前会调用flush方法 刷新缓冲区。关闭后在写的话,会抛IOException

​ */ fw.close();

​ }

}

  1. 实例:

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.io.IOException;

class IODemo

{

​ public static void main(String[] args)

​ {

​ try

​ {

​ //使用FileInputStream和FileOutputStream进行文件复制

​ FileInputStream fis=new FileInputStream(“a.txt”);

​ FileOutputStream fos=new FileOutputStream(“b.txt”);

​ int read;

​ //read=fis.read();

​ byte b[]=new byte[1024];

​ //读取文件,存入字节数组b,返回读取到的字符数,存入read,默认每次将b数组装满

​ read=fis.read(b);

​ while(read!=-1)

​ {

​ fos.write(b,0,read);

​ read=fis.read(b);

​ //read=fis.read();

​ }

​ fis.close();

​ fos.close();

​ }

​ catch (IOException e)

​ {

​ e.printStackTrace();

​ }

​ }

}

9.用FileReader 和 FileWriter 写的复制文本文件的小程序。

package IOtest;

import java.io.FileNotFoundException;

import java.io.FileReader;

import java.io.FileWriter;

import java.io.IOException;

public class TxtCopy {

​ /**

​ * 将C:\的myHeart.txt copy 到 D:\下

​ *

​ * 首先创建Reader读取数据数据的 读取流对象。

​ *

​ * @throws FileNotFoundException

​ */

​ public static void main(String[] args) {

​ FileReader fr = null;

​ FileWriter fw = null;

​ try {

​ fr = new FileReader(“C:\my.txt”);

​ fw = new FileWriter(“D:\you.txt”);

​ //读一个字符,写一个字符方法

// int ch = 0;

//

// while ((ch = fr.read()) != -1) {

// fw.write(ch);

// }

​ char []buf = new char[1024];

​ int len = 0;

​ //读一个数组大小,写一个数组大小方法。

​ while((len = fr.read(buf)) != -1){

​ fw.write(buf, 0, len);

​ }

​ } catch (Exception e) {

​ System.out.println(e.toString());

​ } finally {

​ if (fr != null)

​ try {

​ fr.close();

​ } catch (Exception e2) {

​ throw new RuntimeException(“关闭失败!”);

​ }

​ if (fw != null) try {

​ fw.close(); } catch (IOException e) {

​ throw new RuntimeException(“关闭失败!”);

​ }

​ }

​ }

}