Как сохранить собственный класс на диск?

Чтобы сохранить собственный класс (объект) на диск в Android, нужно сериализовать его — то есть преобразовать объект в поток байтов, который можно записать в файл. Существует несколько подходов, выбор зависит от формата хранения, требований к читаемости, производительности и совместимости.

🔹 Основные способы сохранить объект на диск

1. Java Serializable

Класс должен реализовывать интерфейс java.io.Serializable.

✅ Пример:

import java.io.Serializable
data class User(val name: String, val age: Int) : Serializable

Сохранение объекта:

val file = File(context.filesDir, "user.dat")
ObjectOutputStream(FileOutputStream(file)).use { oos ->
oos.writeObject(user)
}

Чтение объекта:

val file = File(context.filesDir, "user.dat")
val user = ObjectInputStream(FileInputStream(file)).use { ois ->
ois.readObject() as User
}

➕ Плюсы:

  • Просто использовать.

  • Встроен в JDK.

➖ Минусы:

  • Не самый эффективный по объему и скорости.

  • Хрупкий: даже маленькие изменения в классе могут нарушить чтение.

2. Kotlin Serializable (kotlinx.serialization)

Современный, безопасный и кросс-платформенный способ сериализации. Поддерживает JSON, ProtoBuf и другие форматы.

Подключение (Gradle):

implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.3")

Класс:

import kotlinx.serialization.\*
import kotlinx.serialization.json.\*
@Serializable
data class User(val name: String, val age: Int)

Сохранение:

val jsonString = Json.encodeToString(user)
File(context.filesDir, "user.json").writeText(jsonString)

Чтение:

val jsonString = File(context.filesDir, "user.json").readText()
val user = Json.decodeFromString<User>(jsonString)

➕ Плюсы:

  • Читаемый формат (JSON).

  • Контролируемая сериализация.

  • Легко работать с REST.

➖ Минусы:

  • Нужно подключать библиотеку.

  • Не подходит для больших бинарных данных.

3. Gson / Moshi (библиотеки для JSON)

Если вы используете Gson или Moshi, можно сериализовать объекты в JSON:

Gson:

val gson = Gson()
val json = gson.toJson(user)
File(context.filesDir, "user.json").writeText(json)

Moshi:

val moshi = Moshi.Builder().build()
val adapter = moshi.adapter(User::class.java)
val json = adapter.toJson(user)

4. Room (если нужно структурированное хранение)

Если объект должен сохраняться как сущность БД — используйте Room.

@Entity
data class User(@PrimaryKey val id: Int, val name: String, val age: Int)

Room сам сохранит объект в SQLite, и чтение будет через DAO.

5. Proto DataStore / ProtoBuf (для бинарного формата)

Если требуется компактное, бинарное и кроссплатформенное хранение, используйте ProtoBuf с DataStore.

Это требует генерации .proto схем и больше настроек, но даёт высокую эффективность и строгость типов.

⚠️ Важно помнить

  • Для Java Serializable и ObjectOutputStream, поля без Serializable интерфейса (например, Context) вызовут исключение.

  • Не сериализуйте Activity, Context, View — они не предназначены для сохранения.

  • Для долговременного хранения предпочтительнее использовать JSON, Room, ProtoBuf.

Итого

Чтобы сохранить собственный класс на диск:

  • Простое решение — Serializable + ObjectOutputStream.

  • Удобное и безопасное — kotlinx.serialization или Gson/Moshi.

  • Для сложных данных — Room или DataStore.

  • Выбор зависит от: формата, объёма, читаемости и требований к стабильности при изменении модели.