Android 外部存储

2018-02-18 17:09 更新

从外部存储器加载文件

下面的代码显示了如何从外部存储器加载文件。

例子

主布局文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

 <TextView
     android:layout_width="fill_parent"
     android:layout_height="wrap_content"
     android:text="Please enter some text" />

 <EditText
     android:id="@+id/txtText1"
     android:layout_width="fill_parent"
     android:layout_height="wrap_content" />

 <Button
     android:id="@+id/btnSave"
     android:text="Save"
     android:layout_width="fill_parent"
     android:layout_height="wrap_content"
     android:onClick="onClickSave" />

 <Button
     android:id="@+id/btnLoad"
     android:text="Load"
     android:layout_width="fill_parent"
     android:layout_height="wrap_content"
     android:onClick="onClickLoad" />

</LinearLayout>

MainActivity.java文件

package cn.w3cschool.myapplication3.app;
//from  www.w3cschool.cn
import android.app.Activity;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;

public class MainActivity extends Activity {
    EditText textBox;
    static final int READ_BLOCK_SIZE = 100;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        textBox = (EditText) findViewById(R.id.txtText1);
    }

    public void onClickLoad(View view) {
        try {
            //SD Storage
            File sdCard = Environment.getExternalStorageDirectory();
            File directory = new File(sdCard.getAbsolutePath() +
                    "/MyFiles");
            File file = new File(directory, "textfile.txt");
            FileInputStream fIn = new FileInputStream(file);
            InputStreamReader isr = new InputStreamReader(fIn);
            char[] inputBuffer = new char[READ_BLOCK_SIZE];
            String s = "";

            int charRead;
            while ((charRead = isr.read(inputBuffer)) > 0) {
                String readString =
                        String.copyValueOf(inputBuffer, 0,
                                charRead);
                s += readString;

                inputBuffer = new char[READ_BLOCK_SIZE];
            }
            textBox.setText(s);
            Toast.makeText(getBaseContext(),
                    "File loaded successfully!",
                    Toast.LENGTH_SHORT).show();
        } catch (IOException ioe) {
            ioe.printStackTrace();
        }
    }
    public void onClickSave(View view) {
        String str = textBox.getText().toString();
        try {
            //SD Card Storage
            File sdCard = Environment.getExternalStorageDirectory();
            File directory = new File(sdCard.getAbsolutePath() +
                    "/MyFiles");
            directory.mkdirs();
            File file = new File(directory, "textfile.txt");
            FileOutputStream fOut = new FileOutputStream(file);
            OutputStreamWriter osw = new
                    OutputStreamWriter(fOut);

            osw.write(str);
            osw.flush();
            osw.close();

            Toast.makeText(getBaseContext(),
                    "File saved successfully!",
                    Toast.LENGTH_SHORT).show();

            textBox.setText("");
        } catch (IOException ioe) {
            ioe.printStackTrace();
        }

    }

}

注意

为了写入外部存储,你需要在AndroidManifest.xml文件中添加WRITE_EXTERNAL_STORAGE的权限:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="cn.w3cschool.Files"
    android:versionCode="1"
    android:versionName="1.0" >

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

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <activity
            android:label="@string/app_name"
            android:name=".FilesActivity" >
            <intent-filter >
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

选择最佳存储选项

在Android应用程式中储存资料有三种主要方法:

  • SharedPreferences对象
  • 内部存储
  • 外部存储

以下是一些准则:

  • 要存储名称/值对,请使用SharedPreferences对象。
  • 要存储临时数据,请使用内部存储。
  • 要与其他用户共享你的应用程序数据,请将文件存储在SD卡上。

保存到外部存储(SD卡)

下面的代码显示了如何保存到外部存储器(SD卡)。

主布局文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

 <TextView
     android:layout_width="fill_parent"
     android:layout_height="wrap_content"
     android:text="Please enter some text" />

 <EditText
     android:id="@+id/txtText1"
     android:layout_width="fill_parent"
     android:layout_height="wrap_content" />

 <Button
     android:id="@+id/btnSave"
     android:text="Save"
     android:layout_width="fill_parent"
     android:layout_height="wrap_content"
     android:onClick="onClickSave" />

 <Button
     android:id="@+id/btnLoad"
     android:text="Load"
     android:layout_width="fill_parent"
     android:layout_height="wrap_content"
     android:onClick="onClickLoad" />

</LinearLayout>

MainActivity.java文件

package cn.w3cschool.myapplication3.app;
//  www.w3cschool.cn
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;

public class MainActivity extends Activity {
    EditText textBox;
    static final int READ_BLOCK_SIZE = 100;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        textBox = (EditText) findViewById(R.id.txtText1);
    }

    public void onClickSave(View view) {
        String str = textBox.getText().toString();
        try
        {
            FileOutputStream fOut =
                    openFileOutput("textfile.txt",
                            MODE_WORLD_READABLE);
            OutputStreamWriter osw = new
                    OutputStreamWriter(fOut);
            osw.write(str);
            osw.flush();
            osw.close();
            Toast.makeText (getBaseContext(),
                    "File saved successfully!",
                    Toast.LENGTH_SHORT).show();
            textBox.setText("");
        }
        catch (IOException ioe)
        {
            ioe.printStackTrace();
        }
    }
    public void onClickLoad(View view) {
        try{
            FileInputStream fIn =
                    openFileInput("textfile.txt");
            InputStreamReader isr = new
                    InputStreamReader(fIn);

            char [] inputBuffer = new char [READ_BLOCK_SIZE];
            String s = "";

            int charRead;
            while ((charRead = isr.read(inputBuffer))>0)
            {
                String readString =
                        String.copyValueOf(inputBuffer, 0,
                                charRead);
                s += readString;

                inputBuffer = new char [READ_BLOCK_SIZE];
            }
            textBox.setText(s);
            Toast.makeText (getBaseContext(),
                    "File loaded successfully!",
                    Toast.LENGTH_SHORT).show();
        }
        catch (IOException ioe) {
            ioe.printStackTrace();
        }
    }
}

使用文件实用程序写入和读取外部存储

下面的代码显示了如何使用文件实用程序写入和读取外部存储。

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="cn.w3cschool.myapplication3.app" >

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="www.w3cschool.cn"
        android:theme="@style/AppTheme" >
        <activity
            android:name="cn.w3cschool.myapplication3.app.MainActivity"
            android:label="www.w3cschool.cn"
            >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

    </application>

</manifest>

主布局xml文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical">

    <TextView
        android:id="@+id/external_storage_label"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="10px"
        android:text="Enter some text to write on the external storage, then read back:" />

    <EditText
        android:id="@+id/external_storage_input"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="10px" />

    <Button
        android:id="@+id/external_storage_write_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Write" />

    <Button
        android:id="@+id/external_storage_read_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Read" />

    <TextView
        android:id="@+id/external_storage_output"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="10px" />


</LinearLayout>

主Activity Java代码

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import android.os.Environment;
import android.util.Log;
/*www.w3cschool.cn*/

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.nio.channels.FileChannel;

import java.io.File;

public class MainActivity extends Activity {
   private EditText input;
   private TextView output;
   private Button write;
   private Button read;

   @Override
   public void onCreate(final Bundle icicle) {
      super.onCreate(icicle);
      this.setContentView(R.layout.external_storage);

      this.input = (EditText) findViewById(R.id.external_storage_input);
      this.output = (TextView) findViewById(R.id.external_storage_output);

      this.write = (Button) findViewById(R.id.external_storage_write_button);
      this.write.setOnClickListener(new OnClickListener() {
         public void onClick(final View v) {
            write();
         }
      });

      this.read = (Button) findViewById(R.id.external_storage_read_button);
      this.read.setOnClickListener(new OnClickListener() {
         public void onClick(final View v) {
            read();
         }
      });
   }

   private void write() {
      if (FileUtil.isExternalStorageWritable()) {
         File dir = FileUtil.getExternalFilesDirAllApiLevels(this.getPackageName());
         File file = new File(dir, "test.txt");
         FileUtil.writeStringAsFile(input.getText().toString(), file);
         Toast.makeText(this, "File written", Toast.LENGTH_SHORT).show();
         input.setText("");
         output.setText("");
      } else {
         Toast.makeText(this, "External storage not writable", Toast.LENGTH_SHORT).show();
      }
   }

   private void read() {
      if (FileUtil.isExternalStorageReadable()) {
         File dir = FileUtil.getExternalFilesDirAllApiLevels(this.getPackageName());
         File file = new File(dir, "test.txt");
         if (file.exists() && file.canRead()) {
            output.setText(FileUtil.readFileAsString(file));  
            Toast.makeText(this, "File read", Toast.LENGTH_SHORT).show();
         } else {
            Toast.makeText(this, "Unable to read file: " + file.getAbsolutePath(), Toast.LENGTH_SHORT).show();  
         }
      } else {
         Toast.makeText(this, "External storage not readable", Toast.LENGTH_SHORT).show();
      }
   }
}



/**
 * FileUtil methods. 
 * 
 * @author ccollins
 *
 */
final class FileUtil {

   // from the Android docs, these are the recommended paths
   private static final String EXT_STORAGE_PATH_PREFIX = "/Android/data/";
   private static final String EXT_STORAGE_FILES_PATH_SUFFIX = "/files/";
   private static final String EXT_STORAGE_CACHE_PATH_SUFFIX = "/cache/";

   // Object for intrinsic lock (per docs 0 length array "lighter" than a normal Object)
   public static final Object[] DATA_LOCK = new Object[0];

   private FileUtil() {
   }

   /**
    * Use Environment to check if external storage is writable.
    * 
    * @return
    */
   public static boolean isExternalStorageWritable() {
      return Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);
   }

   /**
    * Use environment to check if external storage is readable.
    * 
    * @return
    */
   public static boolean isExternalStorageReadable() {
      if (isExternalStorageWritable()) {
         return true;
      }
      return Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED_READ_ONLY);
   }

   /**
    * Return the recommended external files directory, whether using API level 8 or lower.
    * (Uses getExternalStorageDirectory and then appends the recommended path.)
    * 
    * @param packageName
    * @return
    */
   public static File getExternalFilesDirAllApiLevels(final String packageName) {
      return FileUtil.getExternalDirAllApiLevels(packageName, EXT_STORAGE_FILES_PATH_SUFFIX);
   }
   
   /**
    * Return the recommended external cache directory, whether using API level 8 or lower.
    * (Uses getExternalStorageDirectory and then appends the recommended path.)
    * 
    * @param packageName
    * @return
    */
   public static File getExternalCacheDirAllApiLevels(final String packageName) {
      return FileUtil.getExternalDirAllApiLevels(packageName, EXT_STORAGE_CACHE_PATH_SUFFIX);
   }

   private static File getExternalDirAllApiLevels(final String packageName, final String suffixType) {
      File dir =
               new File(Environment.getExternalStorageDirectory() + EXT_STORAGE_PATH_PREFIX + packageName + suffixType);
      synchronized (FileUtil.DATA_LOCK) {
         try {
            dir.mkdirs();
            dir.createNewFile();
         } catch (IOException e) {
            Log.e(Constants.LOG_TAG, "Error creating file", e);
         }
      }
      return dir;
   }

   /**
    * Copy file, return true on success, false on failure.
    * 
    * @param src
    * @param dst
    * @return
    */
   public static boolean copyFile(final File src, final File dst) {
      boolean result = false;
      FileChannel inChannel = null;
      FileChannel outChannel = null;
      synchronized (FileUtil.DATA_LOCK) {
         try {
            inChannel = new FileInputStream(src).getChannel();
            outChannel = new FileOutputStream(dst).getChannel();
            inChannel.transferTo(0, inChannel.size(), outChannel);
            result = true;
         } catch (IOException e) {

         } finally {
            if (inChannel != null && inChannel.isOpen()) {
               try {
                  inChannel.close();
               } catch (IOException e) {
                  // ignore
               }
            }
            if (outChannel != null && outChannel.isOpen()) {
               try {
                  outChannel.close();
               } catch (IOException e) {
                  // ignore
               }
            }
         }
      }
      return result;
   }

   /**
    * Replace entire File with contents of String, return true on success, false on failure.
    * 
    * @param fileContents
    * @param file
    * @return
    */
   public static boolean writeStringAsFile(final String fileContents, final File file) {
      boolean result = false;
      try {
         synchronized (FileUtil.DATA_LOCK) {
            if (file != null) {
               file.createNewFile(); // ok if returns false, overwrite
               Writer out = new BufferedWriter(new FileWriter(file), 1024);
               out.write(fileContents);
               out.close();
               result = true;
            }
         }
      } catch (IOException e) {
         Log.e(Constants.LOG_TAG, "Error writing string data to file " + e.getMessage(), e);
      }
      return result;
   }

   /**
    * Append String to end of File, return true on success, false on failure.
    * 
    * @param appendContents
    * @param file
    * @return
    */
   public static boolean appendStringToFile(final String appendContents, final File file) {
      boolean result = false;
      try {
         synchronized (FileUtil.DATA_LOCK) {
            if ((file != null) && file.canWrite()) {
               file.createNewFile(); // ok if returns false, overwrite
               Writer out = new BufferedWriter(new FileWriter(file, true), 1024);
               out.write(appendContents);
               out.close();
               result = true;
            }
         }
      } catch (IOException e) {
         Log.e(Constants.LOG_TAG, "Error appending string data to file " + e.getMessage(), e);
      }
      return result;
   }

   /**
    * Read file as String, return null if file is not present or not readable.
    * 
    * @param file
    * @return
    */
   public static String readFileAsString(final File file) {
      StringBuilder sb = null;
      try {
         synchronized (FileUtil.DATA_LOCK) {
            if ((file != null) && file.canRead()) {
               sb = new StringBuilder();
               String line = null;
               BufferedReader in = new BufferedReader(new FileReader(file), 1024);
               while ((line = in.readLine()) != null) {
                  sb.append(line + System.getProperty("line.separator"));
               }
            }
         }
      } catch (IOException e) {
         Log.e(Constants.LOG_TAG, "Error reading file " + e.getMessage(), e);
      }
      if (sb != null) {
         return sb.toString();
      }
      return null;
   }
}
读取外部存储

以上内容是否对您有帮助:
在线笔记
App下载
App下载

扫描二维码

下载编程狮App

公众号
微信公众号

编程狮公众号