Android
File I/O
String Handling
Mobile Development
Java Programming

Read/Write String from/to a File in Android

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

Reading and writing strings to files in Android should use app-internal storage APIs for simplicity and security. Internal storage avoids runtime storage permissions for most cases and keeps data sandboxed. Common issues are incorrect context usage, encoding assumptions, and blocking file IO on the main thread.

Core Sections

1) Write string to internal file

kotlin
1fun writeText(context: Context, fileName: String, content: String) {
2    context.openFileOutput(fileName, Context.MODE_PRIVATE).use { stream ->
3        stream.write(content.toByteArray(Charsets.UTF_8))
4    }
5}

MODE_PRIVATE replaces file content by default.

2) Read string from internal file

kotlin
fun readText(context: Context, fileName: String): String {
    return context.openFileInput(fileName).bufferedReader(Charsets.UTF_8).use { it.readText() }
}

Wrap calls with exception handling for missing files.

3) Java equivalent

java
1String text = "hello";
2try (FileOutputStream fos = context.openFileOutput("note.txt", Context.MODE_PRIVATE)) {
3    fos.write(text.getBytes(StandardCharsets.UTF_8));
4}

Read similarly with openFileInput and InputStreamReader.

4) Threading and reliability

Perform file IO off main thread for larger payloads.

kotlin
withContext(Dispatchers.IO) {
    writeText(context, "note.txt", content)
}

Consider atomic-write patterns for critical data (write temp then rename).

Verification Workflow and Operational Hardening

After implementing the fix, validate with a repeatable workflow rather than ad hoc manual checks. A reliable approach is: reproduce baseline, apply one focused change, then verify both expected behavior and nearby edge cases. This keeps debugging causal and makes reviews easier because every observed improvement is traceable to a specific diff.

A simple validation loop:

bash
1# 1) capture baseline output
2./run_case.sh > before.txt
3
4# 2) apply targeted fix from this article
5# edit code/config only in relevant area
6
7# 3) verify after-state and compare
8./run_case.sh > after.txt
9diff -u before.txt after.txt

For codebases with automated tests, immediately translate the reproduced issue into a regression test. This is the fastest way to prevent recurrence after refactors, dependency upgrades, or runtime migrations.

bash
1# typical quality gate sequence
2./lint.sh
3./test.sh
4./smoke.sh

Edge-case validation is essential. Many failures appear only on boundary inputs such as empty collections, null values, unusual encodings, large payloads, or high concurrency. Build a compact table of edge scenarios with expected outcomes, then run it in local and CI environments. This catches hidden assumptions early and reduces production surprises.

Environment parity also matters. A fix that works locally can fail elsewhere due to version differences, OS behavior, architecture (x86 vs ARM), filesystem semantics, or network policy. Capture runtime metadata alongside results so troubleshooting stays grounded in facts.

bash
1python --version
2node --version
3java -version
4git rev-parse --short HEAD

Before rollout, define rollback criteria and observability signals. Decide in advance which metrics/logs indicate success or regression, and document the rollback command path for on-call responders. Teams recover faster when fallback steps are predefined instead of improvised during incidents.

Finally, isolate functional fixes from broad refactors. Small, focused commits are easier to review, bisect, and revert safely. If normalization, formatting, or dependency upgrades are required, ship them in separate commits to keep risk controlled and diagnosis straightforward.

Common Pitfalls

  • Performing large file reads/writes on UI thread.
  • Ignoring UTF-8 encoding consistency across read and write paths.
  • Assuming file exists without catching FileNotFoundException.
  • Using external storage APIs unnecessarily for private app data.
  • Forgetting file-mode semantics (MODE_PRIVATE overwrite behavior).

Summary

For Android string persistence, internal storage with openFileOutput/openFileInput is the safest default. Use UTF-8 consistently, handle missing files, and move IO to background threads for responsiveness. These patterns provide reliable lightweight storage for app-local text data.

A practical way to keep this solution robust over time is to add one focused regression test and one edge-case test that represent your real production data shape. Re-run those checks whenever dependencies, runtime versions, or infrastructure settings change. This small maintenance habit catches compatibility drift early and prevents recurring incidents that otherwise look like random regressions.


Related reading
Course
Intermediate
27 lessons
14 hours
OOD Fundamentals

Master object-oriented design from first principles, SOLID, design patterns, and classic interview problems with hands-on coding.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.