データのストレージとアクセス - ファイル ストレージの読み取りと書き込み


このセクションの紹介:

ねえ、このタイトルを見て、読者の中には、前の部分を書き終えたのか、と尋ねる人もいると思います。そうですね、例が必要でまだ書き終わっていません。 効率を高めるために、マルチスレッドのようにチュートリアルを並行して作成することにしました。これにより、チュートリアルの作成が速く進む可能性があります。 これまでちょうど 60 記事を書きましたが、入門チュートリアルの完了にはまだ程遠いので、1 か月半から 2 か月以内に完了したいと思っています。 この一連のチュートリアルは本日 9.1 でリリースされるので、頑張ってください~ さて、あまりナンセンスですが、このセクションでは Android データ ストレージと アクセス方法の 1 つは、ファイルの保存と読み書きです。もちろん、この方法に加えて、SharedPreference、データベース、 またはアプリケーションについては、もちろん後ほど説明します。さて、このセクションを始めましょう~


1. Android ファイル操作モード

Java を学習したことのある学生は、新しいファイルを作成するとデータを書き込むことができることを知っています。しかし、Android は異なります。 Linux に基づいて、ファイルの読み取りと書き込みを行う場合、Android での操作モードは次のとおりです:

1.png3. ファイル関連の操作方法。ファイルの読み取りと書き込みの実装


Android でのファイルの読み取りと書き込みは Java でのファイル I/O と同じであり、プロセスも非常に簡単です。以下に簡単な例を書いてみましょう:

2.png

レンダリングの実装:

追記:

作者の N5 には root がなく、ファイル保存ディレクトリを参照できないため、ここではシミュレーターが使用されています。 次に DDMS を開きます。 ファイル エクスプローラーでは、data/data/<パッケージ名>/file に書き込んだファイルがあることがわかります:

3.gif

右上隅にある応答アイコンをクリックして、ファイルをコンピューターにインポートして開きます。書かれた内容を確認します:

4.png

コードの実装:

最初はレイアウト ファイルです: 5.jpgMainActivity.java6.png、ここで関連する操作を完了します:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/LinearLayout1"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.jay.example.filedemo1.MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/nametitle" />

    <EditText
        android:id="@+id/editname"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/detailtitle" />

    <EditText
        android:id="@+id/editdetail"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:minLines="2" />

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <Button
            android:id="@+id/btnsave"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/btnwrite" />

        <Button
            android:id="@+id/btnclean"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/btnclean" />
    </LinearLayout>

    <Button
        android:id="@+id/btnread"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/btnread" />

</LinearLayout>

4. SD カードの

フローチャート

の読み取り:

7.png

コードサンプル:

レンダリングの実行:

8.gif

システムの古いバージョンでは mmtsdcard で直接見つけることができますが、新しいバージョンでは DDMS のファイル エクスプローラーを開きます。 自分で探す必要があるかもしれません:

9.png

sdcard をクリックしますが、/storage/emulated/legacy の下で引き続き探します。さて、彼はまた別の場所にジャンプしました。私たちは引き続き /storage/shell/emirated/0

10.png

を探しました。そして、案の定、SD カード内に生成した test.txt を見つけました。コンピューターにエクスポートして、中身を見てみましょう:

11.png

やあ、SD カードの読み取りと書き込みは成功しました~ 次に、コードがどのように記述されているかを見てみましょう:

12.pngコード実装:

main_activity.xml:

/**
 * Created by Jay on 2015/9/1 0001.
 */
public class FileHelper {

    private Context mContext;

    public FileHelper() {
    }

    public FileHelper(Context mContext) {
        super();
        this.mContext = mContext;
    }

    /*
    * 这里定义的是一个文件保存的方法,写入到文件中,所以是输出流
    * */
    public void save(String filename, String filecontent) throws Exception {
        //这里我们使用私有模式,创建出来的文件只能被本应用访问,还会覆盖原文件哦
        FileOutputStream output = mContext.openFileOutput(filename, Context.MODE_PRIVATE);
        output.write(filecontent.getBytes());  //将String字符串以字节流的形式写入到输出流中
        output.close();         //关闭输出流
    }


    /*
    * 这里定义的是文件读取的方法
    * */
    public String read(String filename) throws IOException {
        //打开文件输入流
        FileInputStream input = mContext.openFileInput(filename);
        byte[] temp = new byte[1024];
        StringBuilder sb = new StringBuilder("");
        int len = 0;
        //读取文件内容:
        while ((len = input.read(temp)) > 0) {
            sb.append(new String(temp, 0, len));
        }
        //关闭输入流
        input.close();
        return sb.toString();
    }

}

次に、SD 操作クラスを作成しましょう:

SDFileHelper.java

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private EditText editname;
    private EditText editdetail;
    private Button btnsave;
    private Button btnclean;
    private Button btnread;
    private Context mContext;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mContext = getApplicationContext();
        bindViews();
    }


    private void bindViews() {
        editdetail = (EditText) findViewById(R.id.editdetail);
        editname = (EditText) findViewById(R.id.editname);
        btnclean = (Button) findViewById(R.id.btnclean);
        btnsave = (Button) findViewById(R.id.btnsave);
        btnread = (Button) findViewById(R.id.btnread);

        btnclean.setOnClickListener(this);
        btnsave.setOnClickListener(this);
        btnread.setOnClickListener(this);
    }


    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btnclean:
                editdetail.setText("");
                editname.setText("");
                break;
            case R.id.btnsave:
                FileHelper fHelper = new FileHelper(mContext);
                String filename = editname.getText().toString();
                String filedetail = editdetail.getText().toString();
                try {
                    fHelper.save(filename, filedetail);
                    Toast.makeText(getApplicationContext(), "数据写入成功", Toast.LENGTH_SHORT).show();
                } catch (Exception e) {
                    e.printStackTrace();
                    Toast.makeText(getApplicationContext(), "数据写入失败", Toast.LENGTH_SHORT).show();
                }
                break;
            case R.id.btnread:
                String detail = "";
                FileHelper fHelper2 = new FileHelper(getApplicationContext());
                try {
                    String fname = editname.getText().toString();
                    detail = fHelper2.read(fname);
                } catch (IOException e) {
                    e.printStackTrace();
                }
                Toast.makeText(getApplicationContext(), detail, Toast.LENGTH_SHORT).show();
                break;
        }
    }
}

次に、

MainActivity.java関連するロジックを実装します:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/LinearLayout1"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.jay.example.filedemo2.MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="清输入文件名" />

    <EditText
        android:id="@+id/edittitle"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="文件名" />


    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="清输入文件内容" />

    <EditText
        android:id="@+id/editdetail"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="文件内容" />

    <Button
        android:id="@+id/btnsave"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="保存到SD卡" />

    <Button
        android:id="@+id/btnclean"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="清空" />

    <Button
        android:id="@+id/btnread"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="读取sd卡中的文件" />

</LinearLayout>

最後に、忘れないでください。 SDカードの読み書き権限を

AndroidManifest.xmlに書き込むためです。

/**
 * Created by Jay on 2015/9/1 0001.
 */
public class SDFileHelper {

    private Context context;

    public SDFileHelper() {
    }

    public SDFileHelper(Context context) {
        super();
        this.context = context;
    }

    //往SD卡写入文件的方法
    public void savaFileToSD(String filename, String filecontent) throws Exception {
        //如果手机已插入sd卡,且app具有读写sd卡的权限
        if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
            filename = Environment.getExternalStorageDirectory().getCanonicalPath() + "/" + filename;
            //这里就不要用openFileOutput了,那个是往手机内存中写数据的
            FileOutputStream output = new FileOutputStream(filename);
            output.write(filecontent.getBytes());
            //将String字符串以字节流的形式写入到输出流中
            output.close();
            //关闭输出流
        } else Toast.makeText(context, "SD卡不存在或者不可读写", Toast.LENGTH_SHORT).show();
    }

    //读取SD卡中文件的方法
    //定义读取文件的方法:
    public String readFromSD(String filename) throws IOException {
        StringBuilder sb = new StringBuilder("");
        if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
            filename = Environment.getExternalStorageDirectory().getCanonicalPath() + "/" + filename;
            //打开文件输入流
            FileInputStream input = new FileInputStream(filename);
            byte[] temp = new byte[1024];

            int len = 0;
            //读取文件内容:
            while ((len = input.read(temp)) > 0) {
                sb.append(new String(temp, 0, len));
            }
            //关闭输入流
            input.close();
        }
        return sb.toString();
    }


}

5. ネイティブシミュレーターのSDカードの問題について

実機でデバッグする場合は、通常は問題ありませんが、ネイティブ仮想マシンの場合は、先に使用します。 Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED) が可能 常に false を返すのは、SD カードが存在しないことです。これが主な問題です。新しいバージョンの SDK がインストールされます。 AVDを作成する際、SDカードの保存領域も同時に適用されます

SDKのバージョンが古い場合やその他の理由で、手動でSDカードを関連付ける必要がある場合があります。設定は次のとおりです。以下:

① 作成された AVD イメージへのパスを見つけます:

クリックして AVD インターフェースを開き、詳細をクリックして、AVD イメージのディレクトリを表示します13.jpg



② AVD イメージが配置されているパスに移動し、コピーしますsdcard.img のパス:

14.jpg

たとえば、私のもの: -sdcard C: UsersAdministrator.androidavdJay4.2.avdsdcard.img

③クリックすると、次のインターフェイスが表示されます:15.jpg

16.jpg

最後に以下を適用して実行します


6. raw フォルダーとassets フォルダー内のファイルを読み込みます

独自のファイルが必要ない場合は、誰もがこの 2 つのフォルダーに精通していると思います。バイナリファイルにコンパイルすると、 これら 2 つのディレクトリにファイルを置くことができ、この 2 つの違いは次のとおりです:

  • res/raw: ファイルは R.java ファイルにマップされ、リソース ID を通じて直接アクセスできます。 。 そして ディレクトリ構造を持つことはできません。つまり、フォルダーを作成することはできません
  • assets: R.java ファイルにマップされず、AssetManager を通じてアクセスできます。つまり、ディレクトリ構造を持つことができます。 独自のフォルダーを作成できます

ファイルリソースの読み取り:

res/raw:

public class MainActivity extends AppCompatActivity implements View.OnClickListener{

    private EditText editname;
    private EditText editdetail;
    private Button btnsave;
    private Button btnclean;
    private Button btnread;
    private Context mContext;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mContext = getApplicationContext();
        bindViews();
    }

    private void bindViews() {
        editname = (EditText) findViewById(R.id.edittitle);
        editdetail = (EditText) findViewById(R.id.editdetail);
        btnsave = (Button) findViewById(R.id.btnsave);
        btnclean = (Button) findViewById(R.id.btnclean);
        btnread = (Button) findViewById(R.id.btnread);

        btnsave.setOnClickListener(this);
        btnclean.setOnClickListener(this);
        btnread.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.btnclean:
                editdetail.setText("");
                editname.setText("");
                break;
            case R.id.btnsave:
                String filename = editname.getText().toString();
                String filedetail = editdetail.getText().toString();
                SDFileHelper sdHelper = new SDFileHelper(mContext);
                try
                {
                    sdHelper.savaFileToSD(filename, filedetail);
                    Toast.makeText(getApplicationContext(), "数据写入成功", Toast.LENGTH_SHORT).show();
                }
                catch(Exception e){
                    e.printStackTrace();
                    Toast.makeText(getApplicationContext(), "数据写入失败", Toast.LENGTH_SHORT).show();
                }
                break;
            case R.id.btnread:
                String detail = "";
                SDFileHelper sdHelper2 = new SDFileHelper(mContext);
                try
                {
                    String filename2 = editname.getText().toString();
                    detail = sdHelper2.readFromSD(filename2);
                }
                catch(IOException e){e.printStackTrace();}
                Toast.makeText(getApplicationContext(), detail, Toast.LENGTH_SHORT).show();
                break;
        }
    }
}

assets:

<!-- 在SDCard中创建与删除文件权限 -->
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
<!-- 往SDCard写入数据权限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

コードのダウンロード:


このセクションの概要:

Android のデータ ストレージとアクセス - ファイルの読み取りと書き込みに関する最初のセクションはこれで終わりです。あなたはこの記事を勉強しています 何か問題が発生したり、間違いがあると思われる場合は、ご指摘ください。ありがとうございます〜