Pustaka io mengatur pembacaan dan penulisan berkas, sedangkan pustaka os menyediakan akses ke waktu sistem, lingkungan, dan nama berkas. Topik ini membahas io.open dengan mode w, a, dan r, metode read, lines, dan close, perbedaan io.write dengan print, serta os.time, os.date, os.rename, dan os.remove. Setiap contoh membuat berkas latihannya sendiri di direktori tempat skrip dijalankan, sehingga berkas tersebut muncul sebentar lalu dihapus dan keluarannya dapat direproduksi. Bahasan ditutup dengan batasan kedua pustaka pada lingkungan tersemat, tempat Lua sering tidak diizinkan menyentuh berkas.
Menulis dan membaca berkas dengan io.open#
Fungsi io.open(nama, mode) membuka berkas dan mengembalikan objek berkas (file handle), yaitu perwakilan berkas yang menyimpan posisi baca dan tulis. Mode w membuka berkas untuk ditulis dari awal dan mengosongkan isi lama, mode a menambahkan di akhir, sedangkan mode r membuka untuk dibaca. Metode write menulis apa adanya tanpa pemindah baris, metode lines mengulang baris demi baris, dan close menutup berkas. Skrip berikut menulis dua catatan, menambahkan satu catatan, lalu membaca seluruh isinya kembali.
-- Menulis, menambah, dan membaca berkas arsip catatan
local f = io.open("arsip-catatan.txt", "w")
f:write("Catatan pertama\n")
f:write("Catatan kedua\n")
f:close()
f = io.open("arsip-catatan.txt", "a")
f:write("Catatan tambahan\n")
f:close()
f = io.open("arsip-catatan.txt", "r")
for baris in f:lines() do
print(baris)
end
f:close()
os.remove("arsip-catatan.txt")Catatan pertama
Catatan kedua
Catatan tambahanBerkas arsip-catatan.txt tercipta di direktori tempat skrip dijalankan, tumbuh dengan mode a, lalu dibaca kembali baris demi baris sebelum dihapus oleh os.remove. Perulangan for baris in f:lines() menghasilkan baris tanpa pemindah baris, sehingga print cukup memanggilnya satu per satu. Skrip yang sama juga memperlihatkan bahwa objek berkas ditutup sebelum dibuka kembali dengan mode yang berbeda.
Apabila berkas yang diminta tidak ada, io.open tidak memunculkan error, melainkan mengembalikan nil beserta pesan error. Bentuk ini menjadikan pola pemeriksaan local f, err = io.open(nama, mode) sebagai langkah pembuka yang aman sebelum metode apa pun dipanggil.
local f, err = io.open("tidak-ada.txt", "r")
print(f)
print(err)nil
tidak-ada.txt: No such file or directoryNilai nil pada baris pertama adalah objek berkas yang gagal dibuat, sedangkan baris kedua menampilkan penyebabnya dari sistem operasi. Pemeriksaan sederhana seperti if f == nil then sudah cukup untuk menahan error berikutnya.
Tiga mode pembacaan read#
Metode read menerima string mode yang menentukan bentuk hasilnya. Mode "l" membaca satu baris tanpa pemindah baris, mode "L" membaca satu baris beserta pemindah barisnya, sedangkan mode "a" membaca seluruh sisa isi berkas. Perbedaan l dan L tampak kecil, tetapi menentukan apakah hasil pembacaan menyatu dengan baris berikutnya. Skrip berikut membuat berkas latihannya sendiri, membacanya dengan ketiga mode, lalu menghapus berkasnya.
-- Berkas latihan dibuat sendiri oleh skrip ini
local f = io.open("mode-baca.txt", "w")
f:write("baris satu\n", "baris dua\n")
f:close()
f = io.open("mode-baca.txt", "r")
local a = f:read("l")
local b = f:read("L")
local c = f:read("a")
print("read l : '" .. a .. "'")
print("read L : '" .. b .. "'")
print("read a : '" .. c .. "'")
f:close()
os.remove("mode-baca.txt")read l : 'baris satu'
read L : 'baris dua
'
read a : ''Keluaran memperlihatkan perbedaannya secara langsung. Hasil read("l") bersih dari pemindah baris, sedangkan hasil read("L") membawa pemindah baris sehingga penutup kutip tercetak pada baris sendiri. Hasil read("a") berupa string kosong karena kedua baris sudah habis dibaca, dan perubahan panjang hasil inilah yang biasa digunakan untuk menandai akhir berkas.
io.write tanpa pemindah baris otomatis#
Fungsi print menambahkan pemindah baris di akhir dan pemisah TAB di antara argumen, sedangkan io.write menulis apa adanya tanpa menambahkan apa pun. Karakteristik ini membuat io.write tepat untuk menyusun satu baris dari beberapa potongan, misalnya label dan angka pada baris log sensor. Angka yang ditulis io.write diformat secara bawaan, sehingga 28.5 tetap tercetak 28.5.
io.write("Sensor 01: ")
io.write(28.5, " derajat C")
io.write("\n")
print("Pencatatan selesai")Sensor 01: 28.5 derajat C
Pencatatan selesaiTiga pemanggilan write menyusun satu baris utuh tanpa spasi tambahan, dan pemindah baris ditulis secara eksplisit dengan "\n". Baris terakhir memperlihatkan print yang melengkapi keluarannya dengan pemindah baris sendiri. Untuk format yang presisi, gabungkan io.write dengan string.format apabila lebar kolom atau jumlah angka desimal perlu diatur.
Waktu dengan os.time dan os.date#
Fungsi os.time(tabel) mengonversi komponen waktu yang diberikan sebagai table, seperti year, month, day, hour, dan min, menjadi epoch, yakni jumlah detik sejak 1 Januari 1970 pukul 00:00 UTC. Fungsi os.date(format, epoch) bergerak sebaliknya, yaitu menyusun string tanggal dari epoch sesuai kode format seperti %Y, %m, %d, %H, dan %M. Awalan ! pada format membaca epoch sebagai waktu UTC, sehingga keluarannya tidak terpengaruh zona waktu mesin.
local t = os.time({ year = 2026, month = 11, day = 6, hour = 8, min = 30 })
print(t)
print(os.date("!%Y-%m-%d %H:%M", t))1793953800
2026-11-06 08:30Pemanggilan os.time mengembalikan 1793953800 di mesin UTC, dan os.date dengan tanda ! mengubahnya kembali menjadi 2026-11-06 08:30. Pasangan dua arah seperti ini menjadi dasar menyimpan cap waktu (timestamp) ke dalam data dan menampilkannya kembali sesuai kebutuhan.
local epoch = 1793953800
print(os.date("!%d/%m/%Y", epoch))
print(os.date("!%H:%M:%S", epoch))
print(os.date("!%Y-%m-%d %H:%M", epoch))
print(os.date("!%A, %d %B %Y", epoch))06/11/2026
08:30:00
2026-11-06 08:30
Friday, 06 November 2026Kode %d/%m/%Y menyusun tanggal gaya umum, %H:%M:%S menyusun jam, sedangkan %A dengan %B menampilkan nama hari serta nama bulan. Nama tersebut mengikuti pengaturan locale penerjemah, yang pada sistem bawaan berbahasa Inggris, sehingga muncul “Friday, 06 November 2026”. Untuk cap waktu log yang konsisten antarmesin, bentuk !%Y-%m-%d %H:%M:%S adalah pilihan yang paling aman.
Mengelola berkas dengan os.rename dan os.remove#
Fungsi os.rename(lama, baru) mengganti nama atau memindahkan berkas, sedangkan os.remove(nama) menghapusnya. Keduanya mengembalikan true apabila berhasil dan nil beserta pesan error apabila gagal, misalnya karena berkasnya tidak ada. Skrip berikut membuat berkas latihan, mengganti namanya, membaca isinya, lalu menghapusnya.
-- Mengelola berkas latihan dengan os.rename dan os.remove
local f = io.open("latihan.txt", "w")
f:write("isi awal")
f:close()
os.rename("latihan.txt", "catatan-lama.txt")
local ada = io.open("latihan.txt", "r") ~= nil
print("latihan.txt ada : " .. tostring(ada))
local g = io.open("catatan-lama.txt", "r")
print("isi catatan-lama.txt : " .. g:read("a"))
g:close()
os.remove("catatan-lama.txt")
ada = io.open("catatan-lama.txt", "r") ~= nil
print("catatan-lama.txt ada : " .. tostring(ada))latihan.txt ada : false
isi catatan-lama.txt : isi awal
catatan-lama.txt ada : falseSetelah rename, berkas lama tidak ditemukan lagi, sehingga io.open("latihan.txt", "r") mengembalikan nil dan pembandingannya mencetak false. Isi berkas baru tetap utuh karena rename hanya mengubah nama, bukan isinya. Penghapusan di akhir memastikan direktori kembali bersih, dan pemeriksaan kedua mengonfirmasi bahwa berkasnya sudah tidak ada.
Batasan pustaka pada lingkungan tersemat#
Lua dirancang untuk disematkan, sehingga aplikasi host menentukan pustaka mana yang disertakan ke dalam lingkungannya. Host seperti Redis menyediakan Lua untuk skrip tetapi meniadakan io dan sebagian besar os, karena skrip Redis harus aman dan deterministik saat direplikasi. Gim dan aplikasi tersemat lain juga sering menyertakan hanya sebagian pustaka standar, sehingga io.open, os.remove, atau os.getenv bisa saja tidak ada sama sekali.
Keterbatasan yang sama menimpa os.getenv, yang dapat mengembalikan nil untuk variabel apa pun karena host sering mengosongkan lingkungan eksekusinya. Praktik yang aman adalah memperlakukan nilai lingkungan sebagai opsi yang menyediakan nilai bawaan di dalam kode. Dengan disiplin ini, skrip yang sama berjalan penuh di penerjemah mandiri dan tetap aman saat disematkan pada aplikasi host.
Ringkasan#
io.openmengembalikan objek berkas dengan modew,a, ataur, dan kegagalan mengembalikannilbeserta pesan error, bukan melempar error.read("l"),read("L"), danread("a")membaca baris, baris dengan pemindah baris, dan seluruh sisa isi, sedangkanlinesmengulang baris demi baris danclosemenutup berkas.io.writemenulis apa adanya tanpa pemindah baris, berbeda denganprintyang menambah pemisah TAB dan baris baru.os.timemengonversi komponen waktu menjadi epoch yang bergantung zona waktu,os.datedengan tanda!menampilkannya sebagai UTC,os.renamedanos.removemengelola berkas, sedangkan host tersemat sering menonaktifkaniodanos.
Referensi#
- Lua 5.4 Reference Manual — Lua.org — Bagian 6.8 dan 6.9 mendokumentasikan pustaka input-output serta pustaka sistem operasi.
- Programming in Lua — Lua.org — Bab 21 dan 22 membahas pustaka I/O serta pustaka sistem operasi beserta contohnya.