Model I/O Sederhana

21.1 Model I/O Sederhana

Model sederhana mengerjakan semua operasi dalam dua current file. Perpustakaan menginisialisasi current input file seperti proses input standar ( stdin) dan current output file seperti proses keluaran standar ( stdout). Oleh karena itu, manakala kami melaksanakan io.read(), kami membaca satu baris dari standar input.

Kami dapat merubah current file itu dengan fungsi io.input dan io.output . Suatu panggilan seperti io.input(filename) membuka file yang ditentukan (dalam gaya baca) dan menetapkannya sebagai file current input. Dari titik ini, semua masukan akan datang dari file ini, sampai panggilan yang lain ke io.input; io.output mengerjakan suatu pekerjaan serupa untuk keluaran. Dalam hal kesalahan, kedua fungsi menaikkan kesalahan itu. Jika kami ingin menangani kesalahan secara langsung, kami harus menggunakan io.open, dari model yang lengkap.

Write lebih sederhana dibanding read.fungsi Io.Write sederhana mendapat suatu angka acak dari argumentasi string dan menulisnya menjadi file current output. Angka-Angka dikonversi ke string mengikuti aturan konversi yang umum, untuk kendali penuh di atas konversi ini, kami perlu menggunakan fungsi format, dari perpustakaan string:

> io.write("sin (3) = ", math.sin(3), "\n") --> sin (3) = 0.1411200080598672 > io.write(string.format("sin (3) = %.4f\n", math.sin(3))) --> sin (3) = 0.1411

Menghindari kode seperti io.write(a..b..c), panggilan io.write(a,b,c) memenuhi efek yang sama dengan lebih sedikit sumber daya, seperti menghindari penggabungan. Umumnya, kami perlu menggunakan cetakan untuk quick-and-dirty program, atau untuk debugging, dan menulis ketika kami memerlukan kendali penuh atas keluaran kami:

> print("hello", "Lua"); print("Hi") --> hello Lua --> Hi > io.write("hello", "Lua"); io.write("Hi", "\n") --> helloLuaHi

Tidak sama dengan print, write tidak menambahkan karakter ekstra pada keluaran, seperti tabs atau newlines. Lebih dari itu, write menggunaan file current output, sedangkan write selalu menggunakan keluaran standar. Akhirnya, mencetak secara otomatis menerapkan tostring ke argumentasi nya, dapat juga menunjukkan tabel, fungsi, dan nol.

Fungsi read membaca string dari file current input. Kendali Argumentasi nya:

Panggilan Io.Read("*All") membaca keseluruhan file current input, dimulai dari posisinya yang sekarang. Jika kami berada pada ujung file, atau jika file kosong, panggilan mengembalikan suatu string kosong.

Karena Lua menangani string-string yang panjang secara efisien, suatu teknik sederhana untuk menulis filters pada Lua adalah membaca keseluruhan file ke dalam suatu string, melakukan pengolahan string( seperti gsub), dan kemudian metulis string kepada keluaran:

t = io.read("*all") -- read the whole file t = string.gsub(t, ...) -- do the job io.write(t) -- write the file

Sebagai contoh, kode berikut adalah suatu program lengkap untuk mengkodekan suatu isi file menggunakan pengkodean quoted-printable dari MIME. Dalam pengkodean ini, karakter bukan ASCII dikodekan sebagai = XX, di mana XX adalah kode numerik dari karakter dalam hexadecimal. Untuk memelihara konsistensi dari pengkodean, karakter `=ยด harus dikodekan juga. Pola teladan digunakan dalam gsub mengambil semua karakter dengan kode dari 128 sampai 255, ditambah tanda sama dengan.

t = io.read("*all") t = string.gsub(t, "([\128-\255=])", function (c)

return string.format("=%02X", string.byte(c)) end) io.write(t)

Pada Pentium 333MHz, program ini mengambil 0.2 detik untuk mengkonversi suatu file dengan 200K karakter.

Panggilan Io.Read("*Line") mengembalikan garis yang berikutnya dari file masukan yang sekarang, tanpa newline karakter. Manakala kami menjangkau akhir file, panggilan mengembalikan nol ( seperti tidak ada garis berikutnya untuk dikembalikan). Pola teladan ini merupakan default untuk membaca, maka io.read() mempunyai efek yang sama seperti io.read("*line"). Pada umumnya, kami menggunakan pola teladan ini hanya ketika algoritma kami menangani garis demi garis. Cara lainnya, kami menyukai pembacaan keseluruhan file dengan segera, dengan *all, atau di dalam blok, seperti kami lihat nanti. Sebagai contoh sederhana untuk penggunaan pola teladan ini, program berikut menyalin current input menjadi current output, menomori masing-masing garis:

local count = 1 while true do

local line = io.read() if line == nil then break end io.write(string.format("%6d ", count), line, "\n") count = count + 1

end

Untuk mengulang suatu file utuh garis per garis, lebih baik dengan menggunakan io.lines iterator. Sebagai contoh, kami dapat tulis suatu program lengkap ke mengurutkan baris dari suatu file sebagai berikut:

local lines = {} -- read the lines in table 'lines' for line in io.lines() do table.insert(lines, line) end -- sort table.sort(lines) -- write all the lines for i, l in ipairs(lines) do io.write(l, "\n") end

Program pengurutan ini adalah suatu file dengan 4.5 MB ( 32K baris) dalam 1.8 detik ( pada Pentium 333MHz), melawan terhadap 0.6 detik yang diluangkan oleh sistem program pengurutan, yang mana ditulis dalam C dan sangat optimalkan.

Panggilan io.read("*number") membaca suatu bilangan dari file masukan yang sekarang. Ini adalah satu-satunya kasus di mana read mengembalian suatu bilangan, sebagai ganti suatu string. Ketika kami harus membaca banyak angka-angka dari suatu file, ketidakhadiran dari string- string intermediate/antara dapat membuat suatu peningkatan performance. Pilihan *number melompati ruang/spasi sebelum bilangan dan menerima format bilangan seperti - 3, + 5.2, 1000, dan - 3.4e-23. Jika tidak menemukan suatu bilangan di posisi file yang sekarang ( oleh karena format tidak baik atau akhir file), maka akan mengembalikan nol.

Kami dapat memanggil read dengan berbagai pilihan, untuk masing-masing argumentasi, fungsi akan mengembalikan hasil masing-masing . Mungkin kami mempunyai suatu file dengan tiga angka-angka per garis:

Sekarang kami ingin mencetak nilai maksimum dari tiap garis. Kami dapat membaca ketiga angka- angka di dalam panggilan tunggal untuk membaca:

while true do local n1, n2, n3 = io.read("*number", "*number", "*number") if not n1 then break end print(math.max(n1, n2, n3))

end

Setidak-Tidaknya, kami perlu selalu mempertimbangkan alternatif pembacaan keseluruhan file dengan pilihan "*all" dari io.read dan kemudian menggunakan gfind untuk menghentikannya:

local pat = "(%S+)%s+(%S+)%s+(%S+)%s+" for n1, n2, n3 in string.gfind(io.read("*all"), pat) do

print(math.max(n1, n2, n3)) end

Di samping dasar pola teladan read, kami dapat memanggil read dengan suatu bilangan n sebagai argumentasi. Dalam hal ini, read tries digunakan untuk membaca n karakter dari masukan Di samping dasar pola teladan read, kami dapat memanggil read dengan suatu bilangan n sebagai argumentasi. Dalam hal ini, read tries digunakan untuk membaca n karakter dari masukan

local size = 2^13 -- good buffer size (8K) while true do

local block = io.read(size) if not block then break end io.write(block)

end

Sebagai kasus khusus, io.read(0) bekerja sebagai suatu test untuk akhir file yang akan mengembalikan suatu string kosong jika terdapat banyak yang akan dibaca atau nol.