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

Cách tạo file txt trong bộ nhớ trong (Internal Storage) Android

Ghi file text vào Internal Storage Android

Internal Storage là bộ nhớ riêng tư của ứng dụng tại /data/data/package.name/files/. Không cần permission, tự động xóa khi uninstall, an toàn cho dữ liệu nhạy cảm.

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 cần lưu" 
        android:inputType="textMultiLine"
        android:minHeight="120dp"
        android:gravity="top" />

    <Button
        android:id="@+id/save"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Lưu vào Internal Storage"
        android:layout_marginTop="16dp"
        android:layout_gravity="center_horizontal" />

</LinearLayout>

Bước 3: MainActivity.java

package com.example.internalstoragefile;

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.Toast;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

public class MainActivity extends AppCompatActivity {
    Button btnSave;
    EditText edtInput;

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

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

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

            // Thư mục: /data/data/pkg/files/text/
            File dir = new File(getFilesDir(), "text");
            if (!dir.exists()) {
                boolean created = dir.mkdirs();
                if (!created) {
                    Toast.makeText(this, "Không thể tạo thư mục", Toast.LENGTH_SHORT).show();
                    return;
                }
            }

            // File: /data/data/pkg/files/text/sample.txt
            File file = new File(dir, "sample.txt");

            try (FileWriter writer = new FileWriter(file)) {
                writer.write(text);
                writer.flush();
                Toast.makeText(this, "Đã lưu thành công!\nĐường dẫn: " + file.getAbsolutePath(), Toast.LENGTH_LONG).show();
            } catch (IOException e) {
                e.printStackTrace();
                Toast.makeText(this, "Lỗi ghi file: " + e.getMessage(), Toast.LENGTH_LONG).show();
            }
        });
    }
}

Bước 4: AndroidManifest.xml - KHÔNG CẦN QUYỀN

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

    <!-- Internal Storage KHÔNG cần permission nào -->
    <!-- Chỉ cần permission khi truy cập External Storage -->

    <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 và kiểm tra

  1. Nhập văn bản → nhấn "Lưu".
  2. Toast hiển thị đường dẫn file đầy đủ.
  3. Mở Device File Explorer (View → Tool Windows → Device File Explorer).
  4. Điều hướng: data → data → com.example.internalstoragefile → files → text → sample.txt
  5. Kéo file ra máy tính để xem nội dung.

Các phương thức File hữu ích


Context context = getApplicationContext();

// Thư mục files gốc: /data/data/pkg/files/
File filesDir = context.getFilesDir();

// Thư mục cache: /data/data/pkg/cache/ (hệ thống có thể xóa khi thiếu dung lượng)
File cacheDir = context.getCacheDir();

// Tạo file con
File file = new File(filesDir, "data.txt");
File fileInSub = new File(filesDir, "subfolder/data.txt");

// Kiểm tra
file.exists()
file.length()        // Kích thước byte
file.lastModified()  // Thời gian sửa đổi
file.delete()        // Xóa file
file.mkdirs()        // Tạo thư mục đệ quy

Đọc file đã lưu


private String readFromFile(String fileName) {
    File file = new File(getFilesDir(), fileName);
    if (!file.exists()) return null;

    StringBuilder content = new StringBuilder();
    try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
        String line;
        while ((line = reader.readLine()) != null) {
            content.append(line).append("\n");
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
    return content.toString();
}

Ghi file nhị phân (Bitmap, byte[])


private void saveBitmap(Bitmap bitmap, String fileName) {
    File file = new File(getFilesDir(), fileName);
    try (FileOutputStream fos = new FileOutputStream(file)) {
        bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos);
        fos.flush();
    } catch (IOException e) { e.printStackTrace(); }
}

private Bitmap loadBitmap(String fileName) {
    File file = new File(getFilesDir(), fileName);
    if (!file.exists()) return null;
    return BitmapFactory.decodeFile(file.getAbsolutePath());
}

Internal vs External Storage - Tóm tắt

Tiêu chíInternal StorageExternal Storage
PermissionKhông cầnCần (API ≤ 28)
Độ an toànCao (private)Thấp (public)
Dung lượngNhỏ (~MB-GB)Lớn (GB)
Xóa khi uninstallCóKhông (trừ app-specific dir)
Phù hợpSettings, token, cache, logMedia, download, share file

⚠️ Best Practices

  • Luôn dùng try-with-resources (Java 7+) để tự đóng stream.
  • File I/O lớn → chạy background thread (Coroutine, RxJava, Executor).
  • Kiểm tra dung lượng trống: StatFs hoặc getFreeSpace().
  • Dữ liệu cấu trúc phức tạp → dùng JSON (Gson/Moshi) hoặc Protocol Buffers.
  • Log file: xoay vòng (rotate) để tránh lấp đầy bộ nhớ.