Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> Android

Cách lưu danh sách vào file txt và đọc danh sách từ file txt trong Android

Lưu và đọc ArrayList từ file text trong bộ nhớ trong (Internal Storage)

Android cung cấp bộ nhớ riêng tư (private internal storage) tại /data/data/package.name/files/. Dữ liệu ở đây chỉ app truy cập được, tự xóa khi uninstall app.

Bước 1: Tạo dự án

Android Studio → File → New Project.

Bước 2: Giao diện (activity_main.xml)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 
    xmlns:android="https://schemas.android.com/apk/res/android"
    xmlns:tools="https://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity"
    android:orientation="vertical"
    android:padding="16dp">

    <EditText
        android:id="@+id/enterText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="Nhập nội dung ở đây" />

    <Button
        android:id="@+id/save"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Lưu vào file"
        android:layout_marginTop="8dp" />

    <TextView
        android:id="@+id/output"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="16sp"
        android:layout_marginTop="16dp"
        android:text="Nội dung file:" />

</LinearLayout>

Bước 3: MainActivity.java - Đã sửa lỗi logic gốc

package com.example.fileliststorage;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;

public class MainActivity extends AppCompatActivity {
    Button btnSave;
    EditText edtInput;
    TextView txtOutput;
    ArrayList stringList = new ArrayList<>();

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

        btnSave = findViewById(R.id.save);
        edtInput = findViewById(R.id.enterText);
        txtOutput = findViewById(R.id.output);

        // Load dữ liệu cũ khi khởi động
        loadFromFile();

        btnSave.setOnClickListener(v -> {
            String input = edtInput.getText().toString().trim();
            if (input.isEmpty()) {
                Toast.makeText(this, "Vui lòng nhập nội dung", Toast.LENGTH_SHORT).show();
                return;
            }

            // Thêm vào list
            stringList.add(input);
            
            // Ghi đè toàn bộ list ra file (mỗi dòng một item)
            saveToFile();
            
            // Cập nhật UI
            updateOutput();
            edtInput.setText("");
            
            Toast.makeText(this, "Đã lưu: " + input, Toast.LENGTH_SHORT).show();
        });
    }

    // Ghi ArrayList ra file (mỗi phần tử một dòng)
    private void saveToFile() {
        File dir = new File(getFilesDir(), "text");
        if (!dir.exists()) {
            dir.mkdirs();
        }

        File file = new File(dir, "sample.txt");
        
        try (FileWriter writer = new FileWriter(file)) {
            for (String line : stringList) {
                writer.write(line);
                writer.write("\n"); // Xuống dòng
            }
            writer.flush();
        } catch (IOException e) {
            e.printStackTrace();
            Toast.makeText(this, "Lỗi ghi file: " + e.getMessage(), Toast.LENGTH_LONG).show();
        }
    }

    // Đọc file vào ArrayList
    private void loadFromFile() {
        File file = new File(getFilesDir(), "text/sample.txt");
        if (!file.exists()) return;

        stringList.clear();
        
        try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
            String line;
            while ((line = reader.readLine()) != null) {
                if (!line.trim().isEmpty()) {
                    stringList.add(line);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        updateOutput();
    }

    private void updateOutput() {
        StringBuilder sb = new StringBuilder();
        sb.append("Danh sách (").append(stringList.size()).append(" mục):\n");
        for (int i = 0; i < stringList.size(); i++) {
            sb.append(i + 1).append(". ").append(stringList.get(i)).append("\n");
        }
        txtOutput.setText(sb.toString());
    }
}

Bước 4: AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="https://schemas.android.com/apk/res/android"
    package="com.example.fileliststorage">

    <!-- Internal storage KHÔNG cần quyền WRITE_EXTERNAL_STORAGE / READ_EXTERNAL_STORAGE -->
    <!-- Chỉ cần quyền này nếu ghi vào External Storage (SD card) -->

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>

Chạy ứng dụng

  1. Nhập văn bản → nhấn "Lưu vào file" → item thêm vào list và ghi ra file.
  2. Nhập thêm nhiều lần → list tích lũy.
  3. Đóng app → mở lại → dữ liệu vẫn còn (đọc từ file khi onCreate).
  4. Kiểm tra file: Device File Explorer → /data/data/com.example.fileliststorage/files/text/sample.txt

Cải tiến: Lưu/Đọc JSON thay vì text thuần


import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import java.lang.reflect.Type;

// Ghi list dưới dạng JSON
private void saveAsJson() {
    File file = new File(getFilesDir(), "text/list.json");
    try (FileWriter writer = new FileWriter(file)) {
        new Gson().toJson(stringList, writer);
    } catch (IOException e) { e.printStackTrace(); }
}

// Đọc JSON về list
private void loadFromJson() {
    File file = new File(getFilesDir(), "text/list.json");
    if (!file.exists()) return;
    try (FileReader reader = new FileReader(file)) {
        Type type = new TypeToken>(){}.getType();
        stringList = new Gson().fromJson(reader, type);
        if (stringList == null) stringList = new ArrayList<>();
    } catch (IOException e) { e.printStackTrace(); }
}

Internal vs External Storage

Đặc điểmInternal StorageExternal Storage
Đường dẫn/data/data/pkg/files//sdcard/ hoặc /storage/emulated/0/
QuyềnKhông cần permissionCần READ/WRITE_EXTERNAL_STORAGE
Truy cập app khácKhông (private)Có (public)
Xóa khi uninstallCóKhông (trừ thư mục app-specific)
Dung lượngHạn chếLớn

⚠️ Lưu ý

  • File I/O nên chạy trên background thread (RxJava, Coroutines, AsyncTask) cho file lớn.
  • Dùng try-with-resources (API 19+) để tự đóng stream.
  • Xử lý IOException đúng cách.
  • Internal storage phù hợp: cache, settings, log, dữ liệu nhạy cảm.