File, Direktori & JSON
Membaca dan menulis berkas dengan dart:io, input dari keyboard, mengubah data ke/dari JSON dengan dart:convert, dan menyimpan data aplikasi ke berkas.
Menyimpan data agar tidak hilang
Variabel hilang begitu program selesai. Agar data bertahan, simpan ke berkas. Dart menyediakan pustaka dart:io untuk berkas dan folder, dan dart:convert untuk mengubah data ke teks JSON.
Membaca dan menulis berkas teks
import 'dart:io';
Future<void> main() async {
var berkas = File('catatan.txt');
await berkas.writeAsString('Baris 1\nBaris 2\n'); // menimpa isi
await berkas.writeAsString('Baris 3\n', mode: FileMode.append); // menambah
if (await berkas.exists()) {
String isi = await berkas.readAsString();
List<String> baris = await berkas.readAsLines();
print(baris.length); // 3
}
await berkas.delete();
}
Method di atas bersifat asinkron (Future) sehingga tidak memblokir program. Versi sinkron tersedia dengan akhiran Sync: readAsStringSync(), writeAsStringSync(). Versi sinkron lebih ringkas untuk skrip kecil.
Membaca berkas besar sebagai Stream
import 'dart:convert';
var baris = File('log.txt')
.openRead()
.transform(utf8.decoder)
.transform(LineSplitter());
await for (var b in baris) {
print(b);
}
Direktori dan path
var folder = Directory('data');
if (!await folder.exists()) {
await folder.create(recursive: true);
}
await for (var item in folder.list()) {
print(item.path);
}
print(Directory.current.path); // folder kerja saat ini
print(Platform.pathSeparator); // '/' atau '\'
Input dari keyboard
stdout.write('Nama: ');
String? nama = stdin.readLineSync(); // null jika input ditutup
print('Halo, ${nama ?? 'Tamu'}!');
stdout.write('Umur: ');
int umur = int.tryParse(stdin.readLineSync() ?? '') ?? 0;
readLineSync() mengembalikan String?; tangani null dengan ??. Untuk mengubah teks ke angka pakai int.tryParse agar tidak crash.
JSON: format pertukaran data
JSON adalah teks ringan untuk menyimpan data terstruktur, dipakai hampir semua API web. Contoh:
{"nama": "Budi", "umur": 25, "hobi": ["baca", "coding"], "aktif": true}
import 'dart:convert';
// Objek Dart -> teks JSON
var data = {'nama': 'Budi', 'umur': 25, 'hobi': ['baca', 'coding']};
String teks = jsonEncode(data);
print(teks); // {"nama":"Budi","umur":25,"hobi":["baca","coding"]}
// Teks JSON -> objek Dart
var hasil = jsonDecode(teks); // bertipe dynamic
Map<String, dynamic> peta = hasil as Map<String, dynamic>;
print(peta['nama']); // Budi
List<dynamic> hobi = peta['hobi'];
| JSON | Dart |
|---|---|
object {} | Map<String, dynamic> |
array [] | List<dynamic> |
| string / number / true,false / null | String / int, double / bool / null |
Model: class dengan toJson dan fromJson
Bekerja dengan Map<String, dynamic> mudah salah ketik. Praktik standar: buat class model dengan dua method konversi.
class Pengguna {
final String nama;
final int umur;
Pengguna({required this.nama, required this.umur});
factory Pengguna.fromJson(Map<String, dynamic> json) => Pengguna(
nama: json['nama'] as String,
umur: json['umur'] as int,
);
Map<String, dynamic> toJson() => {'nama': nama, 'umur': umur};
}
var p = Pengguna.fromJson(jsonDecode('{"nama":"Budi","umur":25}'));
print(p.nama);
print(jsonEncode(p.toJson()));
Menyimpan dan memuat objek ke berkas
Future<void> simpan(List<Pengguna> daftar) async {
var teks = jsonEncode(daftar.map((p) => p.toJson()).toList());
await File('pengguna.json').writeAsString(teks);
}
Future<List<Pengguna>> muat() async {
var berkas = File('pengguna.json');
if (!await berkas.exists()) return [];
var mentah = jsonDecode(await berkas.readAsString()) as List;
return mentah.map((e) => Pengguna.fromJson(e as Map<String, dynamic>)).toList();
}
JSON yang rapi dibaca manusia: JsonEncoder.withIndent(' ').convert(data).
Menangani berkas/JSON yang rusak
try {
var data = jsonDecode(teksDariBerkas);
} on FormatException {
print('Isi berkas bukan JSON yang valid');
} on FileSystemException catch (e) {
print('Gagal membuka berkas: ${e.message}');
}
Error umum
PathNotFoundException: Cannot open file→ berkas atau folder belum ada; periksa denganexists().type 'int' is not a subtype of type 'String' in type cast→ tipe di JSON tidak sesuaiasyang kamu tulis.FormatException: Unexpected character→ teks bukan JSON valid (koma berlebih, kutip tunggal).