安卓读写文件的方法以及优劣分析

发布时间 2023-12-11 16:27:09作者: 洪信智能

文章摘要

  在Android开发中,数据的存储和读取是应用程序中常见的操作之一。本文将详细介绍Android中读写文件的方法,并对其优劣进行分析。同时,将附上相应的实现代码,以便读者更好地理解

正文

使用JavaIO

  在Android中,我们可以使用Java的文件IO类来读取和写入本地文件系统中的文件。具体来说,可以使用FileInputStream和FileOutputStream类来进行文件的读写操作。这种方式对于小规模数据非常适用,但是当处理大规模数据时,性能可能会受到影响。

优点

  代码简单,易于理解。

  可以处理各种类型的文件,包括大文件。

缺点

  对于小文件,性能可能较差。

  需要手动管理文件读写操作,容易出现异常。

代码示例

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.io.IOException;

 

public class FileIOExample {

    public static void main(String[] args) {

        try {

            FileInputStream fis = new FileInputStream("input.txt");

            FileOutputStream fos = new FileOutputStream("output.txt");

 

            int data;

            while ((data = fis.read()) != -1) {

                fos.write(data);

            }

 

            fis.close();

            fos.close();

        } catch (IOException e) {

            e.printStackTrace();

        }

    }

}

 

使用Android特有的文件访问API

  Android提供了特有的文件访问API,允许我们以更安全和方便的方式访问文件。我们可以使用Context类中的openFileInput()和openFileOutput()方法来访问应用程序特定的文件。这种方式相较于直接读取本地文件系统更为安全和便捷。

优点

  安全便捷,适用于应用程序内部

缺点

  只能访问应用程序特定的文件,无法直接访问外部存储。

代码示例

// 获取 Context 对象 

Context context = getApplicationContext();

// 打开文件 

FileInputStream fis = context.openFileInput("file.txt");

// 使用 FileInputStream 对象读取文件 

byte[] buffer = new byte[1024];

int length;

while ((length = fis.read(buffer)) != -1) {

// 处理读取的数据 

}

// 关闭流 

fis.close();

 

使用AssetManager

优点

  可以读取应用程序内部的资源文件。

  代码简单,易于使用。

缺点

  只能读取应用程序内部的资源文件,无法读取外部存储设备上的文件。

  对于大文件,性能可能较差。

 

代码示例

AssetManager am = getAssets();

InputStream is = am.open("file.txt");

 

使用MediaStore API读取外部存储

 

  对于外部存储,我们可以使用MediaStore API来读取其中的文件。MediaStore API是一个强大的工具,可以访问外部存储中的图片、视频、音频等媒体文件。这种方式适用于需要读取大量媒体文件的情况。

优点

  适用于外部存储,可读取大量媒体文件。

缺点

  对于非媒体文件,可能无法满足需求。

代码示例

// 获取 ContentResolver 对象

ContentResolver resolver = getContentResolver();

 

// 创建一个用于查询 MediaStore 的 Uri

Uri queryUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;

 

// 创建一个用于指定查询条件的 Selection 参数

String selection = MediaStore.Images.Media.MIME_TYPE + "=?";

 

// 创建一个用于指定查询参数的 String[] 参数

String[] selectionArgs = new String[]{"image/jpeg"};

 

// 创建一个用于指定排序方式的 SortOrder 参数

String sortOrder = MediaStore.Images.Media.DATE_ADDED + " DESC";

 

// 执行查询操作,获取 Cursor 对象

Cursor cursor = resolver.query(queryUri, null, selection, selectionArgs, sortOrder);

 

// 使用 Cursor 对象遍历结果,并处理每个结果项

if (cursor != null && cursor.moveToFirst()) {

    do {

        // 获取当前行中的数据

        long id = cursor.getLong(cursor.getColumnIndex(MediaStore.Images.Media._ID));

        String path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));

 

        // 处理图片数据

        Log.d("TAG", "Image ID: " + id);

        Log.d("TAG", "Image Path: " + path);

 

    } while (cursor.moveToNext());

}

 

// 关闭 Cursor 对象,以释放系统资源

if (cursor != null) {

    cursor.close();

}

 

 

  由于使用MediaStore API需要权限,因此需要在Manifest文件中添加相应的权限声明。同时,需要注意在使用该API时,需要使用Cursor对象来获取数据。

使用ContentResolver

优点

  可以读取系统提供的各种数据,如联系人、短信等。

  可以读取外部存储设备上的文件。

缺点

  代码相对复杂,需要了解AndroidContentProvider机制。

  对于大文件,性能可能较差。

代码示例

Uri uri = Uri.parse("content://media/external/images/media/1");

ContentResolver resolver = getContentResolver();

InputStream is = resolver.openInputStream(uri); // 使用 InputStream 对象读取文件

使用SharedPreferences

优点

  可以存储和读取简单的键值对数据。

  代码简单,易于使用。

缺点

  只能存储和读取简单的键值对数据,无法处理复杂的数据结构。

  数据存储在应用程序的私有目录中,无法共享给其他应用程序。

代码示例

  // 写入数据

        SharedPreferences preferences = getSharedPreferences(PREFERENCES_NAME, Context.MODE_PRIVATE);

        SharedPreferences.Editor editor = preferences.edit();

        editor.putString(KEY_NAME, "example data");

        editor.apply();

 

        // 读取数据

        String data = preferences.getString(KEY_NAME, null);

        Log.d("SharedPreferencesExample", data);

 

使用 FileChannel

  这种方法适用于高效地读取和写入大文件。

优点

  支持零拷贝操作,可以在多个线程之间共享文件通道。

缺点

  需要手动管理缓冲区,可能导致性能问题。

代码示例

FileInputStream fis = new FileInputStream(file);

FileChannel channel = fis.getChannel();

ByteBuffer buffer = ByteBuffer.allocate(1024);

while (channel.read(buffer) > 0) {    

buffer.flip();    // 处理读取的数据    

buffer.clear();

}

channel.close();

fis.close();

 

使用DocumentsProvider API读取外部存储

  DocumentsProvider API是一种更为通用的方式,可以访问外部存储中的任何类型的文件。通过DocumentsProvider API,我们可以创建自己的文件浏览器,并使用户能够方便地访问应用程序无法直接访问的文件。这种方式相较于MediaStore API更为通用。

优点

  适用于外部存储,可访问任何类型的文件。

缺点

  开发难度较大,需要自己构建文件浏览器。

总结

  每种方法都有其特定的应用场景和优缺点。在选择读写文件的方法时,需要根据具体的需求和场景进行选择,可以帮助你更好地优化应用程序的性能和用户体验。