zoukankan      html  css  js  c++  java
  • Java中的文件读写

     序言

      之前做项目的时候经常使用文件读写相关的功能,但当时忙于赶进度,只是慌忙地copy实现功能,并没有仔细分析其运作原理,今天来仔细学习一下。

     正文

    1.文件读写相关的类

    (1) java.io.InputStream: 抽象类,输入字节流,可以将本输入流中的字节读取出来。

      主要方法: void read(byte[] b):从输入流中读取一定数量的字节,将其存储在缓冲区数组b中。

    (2) java.io.OutputStream: 抽象类,输出字节流,可以接收待输出的字节并将这些字节发送到某个接收器。

         主要方法: void write(byte[] b):接收byte数组中的字节,将byte数组中的字节写入此输出流。

    (3) FileInputStream: 是InputStream的子类,文件输入流,可以从文件系统中的某个文件中获得输入字节。

      主要方法: FileInputStream FileInputStream(File file):通过打开一个到实际文件的连接来创建一个文件输入流,该文件通过File对象指定。

              void read(byte[] b):将此文件输入流中将最多b.length个字节的数据读入一个byte数组b中。

    (4) FileOutputStream: 是OutputStream的子类,文件输出流,可以从byte数组中接收数据并将数据写入某个文件。

      主要方法: FileOutputStream FileOutputStream(File file):创建一个准备向file所表示的文件中写入数据的文件输出流。

           void write(byte[] b):将byte数组b中的字节写入此文件输出流。

    (5) File: 文件或目录路径名的抽象表示形式,此类的实例可能表示实际的文件系统对象(一个文件或一个目录),也可能不表示实际的文件系统对象。File类的实例时不可变的,一旦创建,其对象表示的抽象路径名将永不改变。

      主要方法: File File(String pathname):通过将给定的路径名字符串pathname转换为抽象路径来创建一个新的File实例。

            boolean delete():删除此抽象路径名表示的文件或目录。

            boolean exists():测试此抽象路径名表示的文件或目录是否实际存在。

            String getAbsolutePath():返回此抽象路径名的绝对路径名字符串(带盘符)。

            String getPath():将此抽象路径名转换成一个路径名字符串。

            String getParent():返回此抽象路径名的父目录的路径名字符串,如果没有父目录则返回null。

            boolean isDirectory():测试此抽象路径名表示的文件是否是一个目录,只有是目录且实际存在才会返回true。

            boolean isFile():测试此抽象路径名表示的文件是否是一个标准文件,只有是标准文件且实际存在才会返回true。

            String[] list():返回一个字符串数组,这些字符串指定此抽象路径名所表示的目录中的文件了目录,即返回一个文件夹下所有的文件名和文件夹名。

            boolean mkdir():创建此抽象路径名指定的目录,即创建文件夹。如果此路径中有不存在的父文件夹,则创建失败,返回false。

                 boolean mkdirs():创建此抽象路径名指定的目录,包括所有必需但不存在的父目录。

            boolean createNewFile():当且仅当不存在此抽象路径名指定的文件时,不可分地创建一个新的空文件。

    (6) DataInputStream: java.io.FilterInputStream的子类,数据输入流,允许应用程序以与机器无关的方式从底层输入流中读取基本Java数据类型。

      主要方法: DataInputStream DataInputStream(InputStream in):使用指定的底层InputStream创建一个DataInputStream。

           String readUTF():读入一个使用UTF-8格式编码的字符串,以String形式返回此字符串。

    (7) DataOutputStream: java.io.FilterOutputStream的子类,数据输出流,允许应用程序以适当的方式将Java基本数据类型的数据写入输出流中。

      主要方法: DataOutputStream DataOutputStream(OutputStream out):使用指定的底层OutputStream创建一个新的数据输出流。

            void writeUTF(String str):以与机器无关的方式使用UTF-8编码将一个字符串写入基础输出流。

    (8) InputStreamReader: java.io.Reader的子类,是字节流(文件)通向字符流的桥梁,可以使用指定的字符集读取字节,并将其解码为字符。

      主要方法: InputStreamReader InputStreamReader(InputStream in,CharSet c s):由输入流对象创建使用指定字符集的InputStreamReader。

            int read():读取单个字符。

    (9) OutputStreamWriter: java.io.Writer的子类,是字符流通向字节流(文件)的的桥梁,可使用指定的字符集将要写入流中的字符编码成字节。

      主要方法: OutputStreamWriter OutputStreamWriter(OutputStream out,Charset cs):由输出流对象创建使用指定符集的OutputStreamWriter。

            void write(int c):写入单个字符。

            void write(String str,int off,int len):写入字符串的一部分到文件中。

    (10) BufferedReader: java.io.Reader的子类,从字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取。

       主要方法: BufferedReader BufferedReader(Reader in):创建一个使用默认大小输入缓冲区的缓冲字符输入流。

             int read():读取单个字符。

            String readLine():读取一行文本。

    (11) BufferedWriter: java.io.Writer的子类,将文本写入字符输出流,缓冲各个字符,提供单个字符、数组和字符串的高效写入。

       主要方法: BufferedWriter BufferedWriter(Writer out):创建一个使用默认大小输出缓冲区的缓冲字符输出流。

            void write(int c):写入单个字符。

            void write(String s,int off,int len):写入字符串的某一部分到文件中。

            void newLine():写入一个行分隔符。

    (12) FileReader: java.io.InputStreamReader的子类,是用来读取字符文件的便捷类,用于读取字符流。此类的构造方法默认的字符编码和默认字节缓冲区大小都是适当的。

        主要方法: FileReader FileReader(File file):为给定的File对象创建一个新的FileReader。

    (13) FileWriter: java.io.OutputStreamWriter的子类,是用来写入字符文件的便捷类,用于写入字节流。如果要写入原始字节流,则考虑使用FileOutputStream。

           主要方法: FileWriter FileWriter(File file):为给定的FIle对象创建一个新的FileWriter。

    (14) PrintWriter: java.io.Writer的子类,向文本输出流打印对象的格式化表示形式,不包含用于写入原始字节的方法。

       主要方法: PrintWriter PrintWriter(File file,String csn): 使用指定文件和字符集创建一个不具有自动行刷新的新PrintWriter对象。

                        PrintWriter PrintWriter(OutputStream out,boolean autoFlush):根据现有的OutputStream创建新的PrintWriter对象。

                        PrintWriter PrintWriter(Writer out,boolean autoFlush):根据Writer创建新的PrintWriter。

                        PrintWriter append(CharSequence):将指定的字符序列添加到此writer。

           void println(String x):打印字符串到文件中,然后终止该行。

             void write(String s):写入字符串道文件中。

    (15) PrintStream: java.io.FilterOutputStream的子类,为其他的输出流添加了功能,使他们能够方便地打印各种数据值表示形式。与其他输出流不同,PrintStream永远不会抛出IOException。 

       主要方法:PrintStream PrintStream(File file,String csn):创建具有指定名称和字符集且不带自动行刷新的打印流。

                  PrintStream PrintStream(OutputStream out,boolean autoFlush):根据已有的OutputStream对象创建新的打印流。

             PrintStream append(CharSequence csq):将指定字符序列添加到此输出流。

             void println(String x):打印一行字符串。

             void write(byte[] buf,int off,int len):将len字节从知道那个的初始偏移量为off的byte数组中写入此流。     

    2. 读取文件byte内容并输出到控制台

      读取文件byte内容的处理流程:由文件的File对象生成FileInputStream对象 --> FileInputStream对象调用read函数将文件内容读入byte数组 --> 输出byte数组中的内容到控制台。其实现源代码如下所示,

     1 import java.io.FileInputStream;
     2 import java.io.IOException;
     3 import java.util.Arrays;
     4 
     5 import org.dom4j.DocumentException;
     6 
     7 public class FileIO 
     8 {
     9     void readFile(String filepath)throws IOException
    10     {
    11         File f=new File(filepath);
    12         if(!f.exists())
    13         {
    14             System.out.println("文件"+f.getAbsolutePath()+"不存在!");
    15             return;
    16         }
    17         else
    18         {
    19             FileInputStream fis=new FileInputStream(f);//创建对应f的文件输入流
    20             byte[] b=new byte[(int)f.length()];//创建一个长度等于文件f长度的byte数组,用于存放从文件中读出的数据
    21             fis.read(b);
    22             String str=Arrays.toString(b);
    23             System.out.println(str);
    24             fis.close();   
    25         }
    26     }
    27     
    28     public static void main(String args[])throws IOException, DocumentException
    29     {
    30         FileIO fio=new FileIO();
    31         fio.readFile("WebRoot\\accessed_files\\test.txt");  
    33     }
    34 }

       其中test.txt中只有一行内容:“你好,我是chloe”,运行程序输出的byte数组内容为

    [-60, -29, -70, -61, -93, -84, -50, -46, -54, -57, 99, 104, 108, 111, 101]

    3. 向文件中写入byte数据

      向文件中输入byte数据的处理过程:由文件的File对象生成FileOutputStream对象 --> FileOutputStream对象调用write函数将byte数组中的内容写入文件。其实现源代码如下

     1 package chloe.fileio;
     2 import java.io.File;
     3 import java.io.FileInputStream;
     4 import java.io.FileOutputStream;
     5 import java.io.IOException;
     6 import java.util.Arrays;
     7 
     8 import org.dom4j.DocumentException;
     9 
    10 public class FileIO 
    11 {    
    12     void writeToFile(String filepath,byte b[])throws IOException
    13     {
    14         File f=new File(filepath);
    15         if(!f.exists())
    16         {
    17             f.createNewFile();
    18             System.out.println("文件"+f.getPath()+"已创建");
    19         }
    20         FileOutputStream fos=new FileOutputStream(f);
    21         fos.write(b);
    22         System.out.println("文件内容写入完毕");
    23     }
    24     
    25     public static void main(String args[])throws IOException, DocumentException
    26     {
    27         FileIO fio=new FileIO();
    28         byte[] b=new byte[15];
    29         b[0]=(byte)-60;
    30         b[1]=(byte)-29;
    31         b[2]=(byte)-70;
    32         b[3]=(byte)-61;
    33         b[4]=(byte)-93;
    34         b[5]=(byte)-84;
    35         b[6]=(byte)-50;
    36         b[7]=(byte)-46;
    37         b[8]=(byte)-54;
    38         b[9]=(byte)-57;
    39         b[10]=(byte)99;
    40         b[11]=(byte)104;
    41         b[12]=(byte)108;
    42         b[13]=(byte)111;
    43         b[14]=(byte)101;
    44         fio.writeToFile("WebRoot\\accessed_files\\test1.txt", b);
    45                 
    46     }
    47     
    48 }

      运行后打开生成的文件test1.txt,其中的内容为“你好,我是chloe”。

      以上是从文件中读取byte数组数据和向写入byte数组,如果需要直接从文件中读取字符串或者向文件中写入字符串,则要使用类型DataInputStream和DataOutputStream.

    4. 使用DataOutputStream和DataInputStream写入和读取字符串

      写入处理流程:由文件的File对象生成FileOutputStream对象 --> 由FileOutputStream对象生成DataOutputStream对象 --> DataOutputStream对象调用writeUTF函数将字符串写入文件

      读取处理流程:由文件的File对象生成FileInputStream对象 --> 由FileInputStream对象生成DataInputStream对象 --> DataInputStream对象调用readUTF函数将文件内容读入字符串 --> 输出字符串内容到控制台

          其实现代码如下所示,

     1     void writeStrToFile(String filepath,String str)throws IOException
     2     {
     3         File f=new File(filepath);
     4         if(!f.exists())
     5         {
     6             f.createNewFile();
     7             System.out.println("文件"+f.getPath()+"已创建");
     8         }
     9         FileOutputStream fos=new FileOutputStream(f);
    10         DataOutputStream dos=new DataOutputStream(fos);
    11         dos.writeUTF(str);
    12         System.out.println("文件内容写入完毕");
    13         dos.close();
    14         fos.close();
    15     }
    16     
    17     String readStrFromFile(String filepath)throws IOException
    18     {
    19         String result;
    20         File f=new File(filepath);
    21         if(!f.exists())
    22         {
    23             System.out.println("文件"+f.getAbsolutePath()+"不存在!");
    24             return "";
    25         }
    26         else
    27         {
    28             FileInputStream fis=new FileInputStream(f);//创建对应f的文件输入流
    29             DataInputStream dis=new DataInputStream(fis);
    30             result=dis.readUTF();//只有先用DataOutputStream的write方法写入合规则的数据后才能正常读出内容
    31             dis.close();
    32             fis.close();
    33             if (result!=null)
    34                 return result;
    35             else 
    36                 return "";
    37             
    38         }
    39     }
    40     
    41     public static void main(String args[])throws IOException, DocumentException
    42     {
    43         FileIO fio=new FileIO();
    44         fio.writeStrToFile("WebRoot\\accessed_files\\test.txt", "你好,我是Chloe~");
    45         System.out.println("读取的文件内容为:"+fio.readStrFromFile("WebRoot\\accessed_files\\test.txt"));
    46         
    47         
    48     }
    49     
    50 }

      运行后输出如下结果,

    1 文件内容写入完毕
    2 读取的文件内容为:你好,我是Chloe~

      注意,使用DataInputStream读取文件内容时,只有读取由DataOutputStream写入的数据才会正常,否则会报EOFException,所以我感觉这两个类不是很好用。

    5. 使用BufferedReader和BufferedWriter写入和读取字符串

       读取字符串时,只要在创建InputStreamReader时指定正确的编码方式,即其编码方式与文件本身的编码方式一致就可以正确读取文件内容,代码如下,

     1     String readLinesFromFile(String filepath) throws IOException
     2     {
     3         String result="";
     4         String line;
     5         File f=new File(filepath);
     6         if(!f.exists())
     7         {
     8             System.out.println("文件"+f.getAbsolutePath()+"不存在!");
     9             return "";
    10         }
    11         else
    12         {
    13             FileInputStream fis=new FileInputStream(f);//创建对应f的文件输入流
    14             InputStreamReader isr=new InputStreamReader(fis,"UTF-8");
    15             BufferedReader br=new BufferedReader(isr);
    16             while((line=br.readLine())!=null)
    17             {
    18                 result=result+line+"\n";
    19             }
    20             return result;    
    21         }
    22     }
    23     public static void main(String args[])throws IOException, DocumentException
    24     {
    25         FileIO fio=new FileIO();
    26         System.out.print(fio.readLinesFromFile("WebRoot\\accessed_files\\test.txt"));
    27     }

      另外,还可以利用更加便捷的写入字符文件的类FileReader实现上述功能,只用将上面的第13~15行改为:

    FileReader fr=new FileReader(f);
    BufferedReader br=new BufferedReader(fr);

      向文件中写入字符串时,创建OutputStreamWriter也尽量要指明编码方式,方便之后正确读取。

     1 void writeLinesToFile(String filepath,String[]strs)throws IOException
     2     {
     3         File f=new File(filepath);
     4         if(!f.exists())
     5         {
     6             f.createNewFile();
     7             System.out.println("文件"+f.getPath()+"已创建");
     8         }
     9         FileOutputStream fos=new FileOutputStream(f);
    10         OutputStreamWriter osw=new OutputStreamWriter(fos,"UTF-8");
    11         BufferedWriter bw=new BufferedWriter(osw);
    12         for(int i=0;i<strs.length;i++)
    13         {
    14             bw.write(strs[i]);
    15             bw.newLine();
    16         }
    17         System.out.println("文件内容写入完毕");
    18         bw.close();
    19         osw.close();
    20         fos.close();
    21     }
    22     public static void main(String args[])throws IOException, DocumentException
    23     {
    24         FileIO fio=new FileIO();
    25         String[] s={"第一行","第二行","   最后一行"};
    26         fio.writeLinesToFile("WebRoot\\accessed_files\\test.txt", s);
    27     }

       类似的,可以用简化类FileWriter实现上述功能,只需将上面第9-11行改成:

    FileWriter fw=new FileWriter(f);
    BufferedWriter bw=new BufferedWriter(fw);
  • 相关阅读:
    [HNOI2010]CITY 城市建设

    [HNOI2011]数学作业
    [NOI2012]美食节
    [HEOI2014]大工程
    [HEOI2013]ALO(待更)
    [HEOI2016/TJOI2016]序列
    贪食蛇(未完待续)
    [HEOI2016/TJOI2016]字符串
    bzoj 2437[Noi2011]兔兔与蛋蛋 黑白染色二分图+博弈+匈牙利新姿势
  • 原文地址:https://www.cnblogs.com/zhouqing/p/2742316.html
Copyright © 2011-2022 走看看