阅读 147

一起Talk Android吧(第二十二回:Java常用类之文件操作二)

各位看官们,大家好,上一回中咱们说的是Java常用类之文件操作的例子,这一回咱们继续说该例子。闲话休提, 言归正转。让我们一起Talk Android吧!

我们在上一回介绍了文件操作,主要是创建和删除文件,那么如何对文件中的内容进行读写操作呢?这时候就需要使用流了,这便是本章回的内容。

输入流与输出流

Java中的流比较多,我们常用的是输入流和输出流。

  • 输入流表示从终端中输入数据到内存中,常用的输入终端是键盘,此外,从位于磁盘上的文件中读取数据也属于输入流。
    复制代码
  • 输出流表示把内存中的数据输出到终端中,常用的输出终端是显示器,此外,把数据输出到磁盘上的文件中也属于输出流。
    复制代码

字节 流与字符流

有了输入流和输出流后,我们是不是可以使用它们操作文件了?暂时还不行,输入流和输出流只是表明数据的流动方向,我们还不知道流中的细节。这两种流可以通过字节或者字符的方式来操作流中的数据。因此,从这个角度来看,我们又把流分为字节流和字符流。通常情况下,我们使用字节流来操作文件,因为系统中传输数据的单位为字节,所以使用字节流来操作文件,以便和系统操持一致。

输入流和输出流有了,字节流和字符流也有了,是不是可以使用它们操作文件了?是的,现在可以了。看官莫急,我们在实际的程序中还需要对字节流进行处理,目的是提高程序的性能。试想一下,每读取一个字节都要访问一次位于硬盘中的文件,那么这样的话,硬盘就不高兴了,因为读取硬盘的开销是比较大的,所以我们常用的做法是把字节数据放到缓冲区中,当缓冲区满了后再去访问硬盘,这样就可以减少访问硬盘的次数,进而提高程序性能。有看官提问:我们还要自己操作缓冲区吗?不需要,Java给我们提供了缓冲流,我们直接使用缓冲流就可以了。

以上这些内容介绍的都是抽象流,大家可能不容易理解,接下来我们介绍具体的流,它们都是Java提供的类,而且有具体的名字。现在请各大常用的流闪亮登场!

FileInputStream

该类属于输入流,用来把文件中的数据输入到内存中,在流中以字节为单位来操作数据,因此也可以叫它字节流。该类提供了read()方法,我们可以使用该方法从文件中读取数据,该方法返回读取到的数据,数据类型为byte,如果到达文件末尾,它将返回-1。下面我们通过伪代码来演示一下:

while(-1 != (data = input.read())
{ 
    byteArray[i] = (byte)data; i++;
} //这里面的input为FileInputStream类型的对象

复制代码

FileOutputStream

该类属于输出流,用来把内存中的数据输出到文件中,在流中以字节为单位来操作数据,因此也可以叫它字节流。该类提供了write()方法,我们可以使用该方法把数据写入到文件中。下面我们通过伪代码来演示一下:

output.write(byteArrary); //这里的byteArray是字节类型的数组,里面存放着将要被写入到文件中的数据
复制代码

BufferedReader

该类属于输入流,用来把文件中的数据输入到内存中,在流中以字符为单位来操作数据,因此也可以叫它字符流。该类提供了read()方法,我们可以使用该方法从文件中读取数据,该方法返回读取到的数据,数据类型为char,如果到达文件末尾,它将返回-1。该方法是重载方法:

read(char buf,int offset, int len)
复制代码

该方法把文件中的字符读取到buf中,并且从buf的offset处开始存放len个字符,如果到达文件末尾,它将返回-1。 该类还提供了一个叫readLine()的方法。该方法常用来从终端中读取数据,每次读取一行数据(遇到换行或者回车符时停止),它返回的数据类型为String,如果到达文件末尾,它将返回-1。下面我们通过伪代码来演示一下:

while(-1 != (data = input.read())
{ 
    charArray[i] = data; i++;
} //这里面的input为BufferedReader类型的对象。

while(null != (strData = input.readLine())
{ 
    stringBuffer.append(strData);
} //这里面的input为BufferedReader类型的对象。
复制代码

BufferedWriter

该类属于输出流,用来把内存中的数据输出到文件中,在流中以字符为单位来操作数据,因此也可以叫它字符流。该类提供了write(ch)方法,我们可以使用该方法把字符ch写入到文件中。该方法是重载方法:

write(String buf,int offset, int len)
复制代码

该方法把buf中的字符串写入到文件中,字符串从buf的offset处开始直到offset+len处结束。该类还提供了一个叫newLine()的方法,该方法常用来在文件中插入一个分隔符。下面我们通过伪代码来演示一下:

output.write(ch); //这里的ch是一个字符
output.write(str); //这里的str是一个字符串
output.write(buf,0,buf.length); //这里的buf是一个String类型的字符串
复制代码

InputStreamReader

该类是转换流,常用来把输入类型的字节流转换为输入类型的字符流。因为缓冲流的操作对象是字符流,所以它经常和缓冲流配合使用。在进行流的转换时,使用它的构造器就可以。

OutputStreamWriter

该类是转换流,常用来把输出类型的字节流转换为输出类型的字符流。因为缓冲流的操作对象是字符流,所以它经常和缓冲流配合使用。在进行流的转换时,使用它的构造器就可以。

看官们,上面是理论知识,光说不练不是我们的风格,接下来我们通过具体的代码来演示如何使用流进行文件操作:

public class FileOp {
    public static String filePath = "H:"+File.separator+"a.txt";
    
    public static void main(String args[]) throws Exception
    {
        File file = new File(filePath);
        FileInputStream inputStream = null;
        FileOutputStream outputStream = null;
        BufferedReader bufReader = null;
        BufferedWriter bufWriter = null;
        String strBuf = null;
        String str = null;
        int i = 0;
        
        if( !file.exists() )    // must check the file state
        {
            if(new File(file.getParent()).exists()) 
                file.createNewFile();
            else
                System.out.println("Parent dir is not exist");
        }
        else
            System.out.println("File is "+filePath+"is existed");
        
        inputStream = new FileInputStream(file);
        outputStream = new FileOutputStream(file);
        bufReader =  new BufferedReader(new InputStreamReader(inputStream));
        bufWriter = new BufferedWriter(new OutputStreamWriter(outputStream));

        for(i=1;i<4;++i)
        {
            strBuf = "The is line: "+i;
            System.out.println("["+strBuf+"]"+" is written into file");
            bufWriter.write(strBuf);
            bufWriter.newLine();
        }
        bufWriter.flush();    // or bufWriter.close();
                
        System.out.println("Reading content from file");
        while(null !=(str = bufReader.readLine()))
            System.out.println(str);
        
        bufReader.close();
        bufWriter.close();
        inputStream.close();
        outputStream.close();   
    }
    
}
复制代码

上面的代码是一种典型的用法,大家可以参考,另外,我们没有使用流中所有的方法,大家可以结合理论部分的内容自己练习。下面是程序的运行结果,请大家参考:

[The is line: 1] is written into file
[The is line: 2] is written into file
[The is line: 3] is written into file
Reading content from file
The is line: 1
The is line: 2
The is line: 3
复制代码

从上面结果中可以看到,我们成功地对文件进行了读写操作。

看官们,最后我们说一下文件操作时的注意事项,单独列出来进行说明,就是希望能够引起大家注意:

  • 1.使用流时都会有I/O异常,因此需要我们进行异常处理。上面的程序中,我们为了方便,直接抛出异常,在实际项目中不能这样处理。
    复制代码
  • 2.使用完流后都需要关闭流,以释放相关的系统资源。
    复制代码
  • 3.最好使用字节流来操作数据,并且配合缓冲流,这样可以提高文件读写效率。
    复制代码

各位看官,关于Java常用类之文件操作的例子咱们就介绍到这里,欲知后面还有什么例子,且听下回分解!

文章分类
Android
文章标签