zoukankan      html  css  js  c++  java
  • 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操作类的结构,所以文章还是有些混乱的。哎,第一次写,时间花了不少,休息啦。 

  • 相关阅读:
    SQLite数据库
    如何将大文件写入到数据库中
    Visual Studio 2008 附加进程调试
    VS2010MFC编程入门
    关于exe文件传递参数方法
    监视剪贴板数据
    Delphi快捷键
    判断一个对象是否存在, 谁更快
    全局探色器
    用DELPHI中实现RAR文件解压到指定一目录
  • 原文地址:https://www.cnblogs.com/supertonny/p/4401214.html
Copyright © 2011-2022 走看看