Android学习一:文件操作

最近在学习安卓相关的编程,对于一门新技术的学习,我想应该跟其他语言一样吧,如C++和C#,也是文件,网络,多线程以及数据库之类的学习了。所以决定先从文件下手,现在将文件的一点学习列在下面:

1.Java中文件的操作

Java中文件的操作分为两种类型:字节型(Stream)和字符型(Reader),但是字符型在处理非文本类型的数据时会有问题。

好了上一段代码:

/**
     * 文件的复制
     * @param srcPath 源文件路径
     * @param destPath 目标文件路径
     * @throws Exception 抛出的异常
     */
    public static void copy(String srcPath, String destPath) throws Exception{
        File src = new File(srcPath);
        File dest = new File(destPath);
        
        InputStream input = new BufferedInputStream(new FileInputStream(src));
        OutputStream output = new BufferedOutputStream(new FileOutputStream(dest));
        
        int len = 0;
        byte[] buffer = new byte[1024];
        while(-1 != (len = input.read(buffer))){
            output.write(buffer,0,len);
        }
        
        output.close();
        input.close();
    }

 

这段代码的主要功能是复制源文件到目标文件,需要特别注意的是,目标文件必须指定文件名,如果是路径的话,会出错。

File src = new File(srcPath);
File dest = new File(destPath);

这两句话的意思是与文件建立联系,以便让后面的流进行操作,当然也可以直接在流中指定文件的路径。

 

InputStream input = new BufferedInputStream(new FileInputStream(src));

这边就是声明输出流了,因为是将外部文件导入到程序中,所以需要使用FileInputStream,这也可以理解。那么BufferedInputStream是有什么作用呢?使用BufferedInputStream对FileInputStream进行装饰,使普通的文件输入流具备了内存缓存的功能,通过内存缓冲减少磁盘IO次数,看到别人博客上的一句话,说的清晰明了就拿过来用了。对于BufferedOutputStream,其作用是类似的。
另外,在input.read()处理到文件末尾的时候就会返回-1,以此来判断文件是否读取结束。对于output.close()内部会调用flush方法将缓存的数据写进文件,最后记得关闭流。

在这里关于异常的是直接抛出的,因为这个方法是逻辑层,所以异常处理交给业务层。

 

2.Android文件的操作

public class FileService {
    private FileService() {

    }

    public static void write(String fileName, String content) throws Exception {
        File file = new File(fileName);// 建立连接
        OutputStream output = new BufferedOutputStream(new FileOutputStream(
                file));
        output.write(content.getBytes());
        output.close();
    }
}

既然在Java中可以使用该代码,那么在android中应这段代码就应该是可用的。但是在执行的时候发生了错误:

打开文件错误:只读文件系统 open failed:EROFS(read only file system)

这是什么原因呢?后来在stack overflow上找到了下面一段话:

You will not have access to the file-system root, which is what you're attempting to access. For your purposes, you can write to internal files new File("test.png"), which places the file in the application-internal storage -- better yet, access it explicitly using getFilesDir().

大致意思是,app没有系统root目录的权限,也就是说,我直接创建file的时候,是在系统的根目录上创建的,然而所写的App没有相关的权限。但是可以写在手机的内部存储器上,通过getFilesDir()来获取内部的目录。更新代码如下:

package org.tonny.util;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.OutputStream;

import android.content.Context;

public final class FileService {
    private Context context;

    public FileService(Context context) {
        this.context = context;
    }

    public void write(String fileName, String content) throws Exception {
        File file = new File(context.getFilesDir() + File.separator + fileName);// 建立连接
        OutputStream output = new BufferedOutputStream(new FileOutputStream(
                file));
        output.write(content.getBytes());
        output.close();
    }
}

这样修改之后,果然可以创建文件了。那么android是否提供了另外的方法来进行相关的操作了,经过一番查阅,发现还是有的,代码如下:

 

package org.tonny.util;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.OutputStream;

import android.content.Context;

public final class FileService {
    private Context context;

    public FileService(Context context) {
        this.context = context;
    }

    public void write(String fileName, String content) throws Exception {
        File file = new File(context.getFilesDir() + File.separator + fileName);// 建立连接
        OutputStream output = new BufferedOutputStream(new FileOutputStream(
                file));
        output.write(content.getBytes());
        output.flush();
        output.close();
    }
    
    public void writeFile(String fileName, String content) throws Exception{
        OutputStream output = new BufferedOutputStream(context.openFileOutput(fileName, Context.MODE_PRIVATE));
        output.write(content.getBytes());
        output.flush();
        output.close();
    }


}

同样是可以在app相应的目录下创建文件。

那么可以在文件的内部存储器存放文件,如何在SD卡上存放文件呢,网上的例子还是比较多的,代码如下:

public void writeSDFile(String fileName, String content) throws Exception {
        boolean sdCardExist = Environment.getExternalStorageState().equals(
                android.os.Environment.MEDIA_MOUNTED);
        if (!sdCardExist) {
            // SD卡不存在,则退出
            return;
        }
        File file = new File(Environment.getExternalStorageDirectory()
                .getPath() + File.separator + fileName);
        OutputStream output = new BufferedOutputStream(new FileOutputStream(
                file));
        output.write(content.getBytes());
        output.flush();
        output.close();
    }

这里需要先判断一下SD卡是否存在,存在才能进一步操作,同时需要在清单文件中配置

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> 

代码是写好了,简单的重构一下:

package org.tonny.util;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;

import android.content.Context;
import android.os.Environment;

public final class FileService {
    private Context context;

    public FileService(Context context) {
        this.context = context;
    }

    public void write(String fileName, String content) throws Exception {
        File file = new File(context.getFilesDir() + File.separator + fileName);// 建立连接
        oper(file, content);
    }

    public void writeFile(String fileName, String content) throws Exception {
        OutputStream output = new BufferedOutputStream(context.openFileOutput(
                fileName, Context.MODE_PRIVATE));
        output.write(content.getBytes());
        output.flush();
        output.close();
    }

    public void writeSDFile(String fileName, String content) throws Exception {
        boolean sdCardExist = Environment.getExternalStorageState().equals(
                android.os.Environment.MEDIA_MOUNTED);
        if (!sdCardExist) {
            // SD卡不存在,则退出
            return;
        }
        File file = new File(Environment.getExternalStorageDirectory()
                .getPath() + File.separator + fileName);
        oper(file, content);
    }

    /**
     * 文件写操作
     * 
     * @param file
     * @param content
     * @throws Exception
     */
    private void oper(File file, String content) throws Exception {
        OutputStream output = new BufferedOutputStream(new FileOutputStream(
                file));
        output.write(content.getBytes());
        output.flush();
        output.close();
    }
}

 

由于学习还在一个较浅的层面,所以就写了这几个简单的例子。还有很多内容有待丰富,如文件的属性获取,复制以及读取等操作都没有写。另外没有从整体上介绍Android IO操作类的结构,所以文章还是有些混乱的。哎,第一次写,时间花了不少,休息啦。 

 

posted @ 2015-04-08 02:14  oneqhw  阅读(331)  评论(0编辑  收藏  举报