ภาพรวม
ตัวอย่างนี้สาธิตการสร้างและเขียนไฟล์ Text (.txt) ลงใน Internal Storage ของแอปพลิเคชัน Android ไฟล์จะถูกเก็บที่ /data/data/<package.name>/files/text/sample.txt ซึ่งเป็นพื้นที่ส่วนตัวของแอป (Private) ไม่ต้องการ Permission และจะถูกลบเมื่อ Uninstall แอป
ขั้นตอนการสร้าง
ขั้นตอนที่ 1: สร้างโปรเจกต์ใหม่
Android Studio → File → New Project → กรอกรายละเอียด
ขั้นตอนที่ 2: จัดรูปแบบหน้าจอ (res/layout/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">
<EditText
android:id="@+id/enterText"
android:hint="กรุณาป้อนข้อความที่นี่"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<Button
android:id="@+id/save"
android:text="บันทึก"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
ขั้นตอนที่ 3: เขียนโค้ด MainActivity (src/MainActivity.java)
package com.example.andy.myapplication;
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 save;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final EditText enterText = findViewById(R.id.enterText);
save = findViewById(R.id.save);
save.setOnClickListener(v -> {
String input = enterText.getText().toString().trim();
if (!input.isEmpty()) {
// สร้างโฟลเดอร์ text ใน Internal Storage
File dir = new File(getFilesDir(), "text");
if (!dir.exists()) {
boolean created = dir.mkdirs();
if (!created) {
Toast.makeText(this, "สร้างโฟลเดอร์ไม่สำเร็จ", Toast.LENGTH_SHORT).show();
return;
}
}
try {
File file = new File(dir, "sample.txt");
// true = append mode (เพิ่มต่อท้าย), false = overwrite (ทับ)
FileWriter writer = new FileWriter(file, true);
writer.append(input).append("\n");
writer.flush();
writer.close();
Toast.makeText(this, "บันทึกข้อความสำเร็จ", Toast.LENGTH_LONG).show();
enterText.setText("");
} catch (IOException e) {
e.printStackTrace();
Toast.makeText(this, "เกิดข้อผิดพลาด: " + e.getMessage(), Toast.LENGTH_LONG).show();
}
} else {
enterText.setError("กรุณาป้อนข้อความ");
}
});
}
}
ขั้นตอนที่ 4: AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="https://schemas.android.com/apk/res/android"
package="com.example.andy.myapplication">
<!-- Internal Storage ไม่ต้องการ Permission -->
<!-- Permission นี้สำหรับ External Storage (API < 29) -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_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>
การทดสอบ
รันแอปพลิเคชัน ป้อนข้อความ กดบันทึก

ข้อความถูกบันทึกสำเร็จ

ตรวจสอบไฟล์ที่: /data/data/<package.name>/files/text/sample.txt

Internal Storage Paths
// ไดเรกทอรีหลักของแอป (Private)
context.filesDir // /data/data/package/files/
context.cacheDir // /data/data/package/cache/ (อาจถูกลบโดยระบบ)
// ไดเรกทอรีเฉพาะประเภท
context.getDir("custom", MODE_PRIVATE) // /data/data/package/app_custom/
// Database
context.getDatabasePath("mydb.db") // /data/data/package/databases/mydb.db
// SharedPreferences
context.getSharedPreferences("prefs", MODE_PRIVATE) // /data/data/package/shared_prefs/prefs.xml
Mode การเปิดไฟล์ (FileWriter Constructor)
// Overwrite (ทับไฟล์เดิม) - Default new FileWriter(file) new FileWriter(file, false) // Append (เพิ่มต่อท้ายไฟล์เดิม) new FileWriter(file, true)
แนวทางปฏิบัติที่ดีกว่า (Modern Android)
1. ใช้ Kotlin Extension Functions
// File Extensions
fun File.writeText(text: String, append: Boolean = false) {
bufferedWriter(append).use { it.write(text) }
}
fun File.readText(): String = bufferedReader().use { it.readText() }
fun File.readLines(): List<String> = bufferedReader().use { it.readLines() }
// Usage
val file = File(context.filesDir, "text/sample.txt")
file.writeText("Hello\n", true) // Append
val content = file.readText()
val lines = file.readLines()
2. ใช้ Coroutines สำหรับ I/O Operations
// Repository Class
class FileRepository @Inject constructor(@ApplicationContext context: Context) {
private val baseDir = File(context.filesDir, "text").apply { mkdirs() }
suspend fun appendText(fileName: String, text: String) = withContext(Dispatchers.IO) {
File(baseDir, fileName).writeText(text + "\n", true)
}
suspend fun readAllText(fileName: String): String = withContext(Dispatchers.IO) {
File(baseDir, fileName).readText()
}
suspend fun readLines(fileName: String): List<String> = withContext(Dispatchers.IO) {
File(baseDir, fileName).readLines()
}
}
3. ใช้ Okio Library (Square)
// build.gradle
implementation "com.squareup.okio:okio:3.9.0"
// Usage
val sink = Okio.buffer(Okio.sink(file))
sink.writeUtf8("Hello").writeUtf8("\n")
sink.close()
val source = Okio.buffer(Okio.source(file))
val text = source.readUtf8()
source.close()
เมื่อไหร่ควรใช้ Internal Storage Text File
| เหมาะสำหรับ | ไม่เหมาะสำหรับ |
|---|---|
| Log/Debug Files | ข้อมูลโครงสร้างที่ต้อง Query/Filter |
| Cache ชั่วคราว | ข้อมูลขนาดใหญ่ (ใช้ Database) |
| Config เรียบง่าย | ข้อมูลที่ต้อง Sync/Backup |
| Export/Import ไฟล์เล็ก | Concurrent Read/Write หลาย Thread |
Best Practices
- ใช้
getFilesDir()สำหรับไฟล์ถาวร,getCacheDir()สำหรับไฟล์ชั่วคราว - รัน I/O บน Background Thread (Dispatcher.IO / Executor)
- ใช้ Try-with-resources / .use() ปิด Stream อัตโนมัติ
- จัดการ Exception และ Disk Space Full
- ตั้งชื่อไฟล์/โฟลเดอร์เป็นภาษาอังกฤษ ไม่มี Space
- สำหรับข้อมูลโครงสร้าง: ใช้ Room Database, DataStore, หรือ JSON + File
สรุป
การเขียนไฟล์ Text ใน Internal Storage ใช้งานง่าย เหมาะสำหรับข้อมูลเล็กๆ แบบ Sequential Access ไม่ต้องการ Permission และปลอดภัย (Private) สำหรับข้อมูลที่ซับซ้อนกว่านี้ ควรพิจารณา Room Database หรือ DataStore