Pada praktik kali ini kita akan membuat program sederhana untuk menulis dan membaca data dari sebuah file. Untuk memudahkan menggunakan data dari file yang di simpan, kita menggunakan struktur struct
dan format data yang disimpan berupa data json.
Kerangka Program
Kerangka program yang akan kita gunakan terdiri dari 4 fungsi sperti ditampilkan pada kerangka program berikut:
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"os"
"strconv"
)
// Struktur Data Penduduk
type Penduduk struct {
ID int
Nama, Alamat string
Umur int
}
// array Daftar data penduduk
type DataPenduduk []Penduduk
//nama file untuk menyimpan data penduduk
const namaFile string = "penduduk.json"
// Fungsi utama program
func main() {
}
// Untuk memuat data penduduk dari file
func (d *DataPenduduk) MuatData() error {
return nil
}
//Menambahkan data penduduk kedalam file
func (d DataPenduduk) Tambah(p Penduduk) error {
return nil
}
// menampilkan daftar data penduduk
func (d DataPenduduk) Daftar() {
}
Pada program yang akan kita buat, kita akan menggunakan struktur dengan nama (type) Penduduk
dan data yang disimpan ke dalam file bernama (type) DataPenduduk
.
Karena data yang akan kita simpan berupa json file maka kita memerlukan paket io/ioutil
untuk membaca dan menyimpan file dengan namaFile
yang telah di deklarasikan daam bentuk variabel, serta encoding/json
untuk memformat type Penduduk
kedalam format json dan sebaliknya.
Tambahan paket yang dibutuhkan adalah paket os
untuk menerima input dari pengguna.
Fungsi Muat Data
Fungsi MuatData
memuat data dari file, fungsi ini akan kita panggil pada fungsi main()
setiap kali program dijalankan sehingga kita bisa memodifikasi data dalam file atau membacanya.
Data yang dimuat dari file akan di format kedalam type DataPenduduk
, seperti yang kita lihat argumen sebelah kiri fungsi ini type DataPenduduk
berupa pointer.
Ini akan memudahkan untuk mengubah nilai varibel type DataPenduduk
dimanapun variabel tersebut dideklarasikan tanpa harus mengembalikan nilai dan menambahkan nilai dengan operator assigment (=
).
// Untuk memuat data penduduk dari file
func (d *DataPenduduk) MuatData() error {
//muat data dari file
data, err := ioutil.ReadFile(namaFile)
if err != nil {
return err
}
// parse data ke dalam bentuk data struct
err = json.Unmarshal([]byte(data), &d)
return err
}
Fungsi Menambahkan Data
Seperti halnya fungsi MuatData()
, fungsi ini juga merupakan fungsi pada type DataPenduduk
.
Bedanya disini DataPenduduk
akan disalin dan dimodifikasi untuk disimpan kedalam file. Dengan argumen type Penduduk
yang akan di tambahkan kedalam DataPenduduk
.
//Menambahkan data penduduk kedalam file
func (d DataPenduduk) Tambah(p Penduduk) error {
id := 1 // id jika belum ada data
if len(d) > 0 { // id jika sudah ada data
id = d[len(d)-1].ID + 1 //increment dari id data sebelumnya
}
p.ID = id //memberi id pada data baru yang akan disimpan
//menggabungkan data baru di Daftar DataPenduduk
d = append(d, p)
// Mengubah data struct Data Penduduk ke dalam format json
json, err := json.Marshal(d)
if err != nil {
return err
}
// menyimpan/menulis ulang data dalam file
err = ioutil.WriteFile(namaFile, json, 0644)
return err
}
Fungsi Untuk Melihat Daftar Data Yang Disimpan
Pada fungsi ini kita hanya menyalin nilai type DataPenduduk
dan menampilkan data pada terminal menggunakan fungsi Println
.
// menampilkan daftar data penduduk
func (d DataPenduduk) Daftar() {
fmt.Println("== Daftar Data Penduduk ==")
// list semua data menggunnakan perulangan
for _, v := range d {
fmt.Println("ID: ", v.ID)
fmt.Println("Nama: ", v.Nama)
fmt.Println("Alamat: ", v.Alamat)
fmt.Println("Umur: ", v.Umur, "\n")
}
}
Fungsi Main
Fungsi main adalah fungsi pertama yang akan dijalankan ketika program di eksekusi. Disini kita menginisialisasi variable data
dengan type DataPenduduk
sebagai wadah data Penduduk
dan variabel input
yang akan menampung setiap inputan pengguna.
// Fungsi utama program
func main() {
input := os.Args
data := DataPenduduk{}
//Memuat data dari file
err := data.MuatData()
if err != nil {
fmt.Println("File belum dibuat atau tidak ditemukan")
}
// Cek input pengguna
if len(input) > 1 {
if len(input) < 4 {
// tampilkan pesan jika inputan tidak lengkap
fmt.Println("Data yang anda isi kurang lengkap\n" +
"format input: \"Nama\" \"Alamat\" umur ")
os.Exit(0)
}
// Jika inputan lengkap maka bisa di proses
umur, _ := strconv.Atoi(input[3])
penduduk := Penduduk{
Nama: input[1],
Alamat: input[2],
Umur: umur,
}
// Menyimpan data kedalam file
data.Tambah(penduduk)
} else {
// Jika tidak ada input argumen
// Maka cukup tampilkan data penduduk
data.Daftar()
}
}
Menjalankan Program
Bagian yang paling menyenangkan adalah mencari tahu hasil program yang telah kita tulis. Untuk menjalankan program gunakan perintah yang biasa digunakan yaitu go run
:
>$ go run main.go
File belum dibuat atau tidak ditemukan
== Daftar Data Penduduk ==
Seperti yang kita lihat, kita memiliki error File belum dibuat atau tidak ditemukan
hal ini karena fungsi MuatData()
tidak menemukan file yang akan dibaca datanya dan data yang ditampilkan oleh fungsi Daftar()
adalah kosong.
Pesan error ini akan hilang ketika kita menambahan data menggunakan argumen seperti berikut:
go run main.go "Yaka" "Yogyakarta" 19
Setelah menjalankan perintah diatas pesan error tetap muncul, hal ini dikarenakan program akan menjalankan fungsi MuatData()
pertama kali setiap program dijalankan.
Pesan error akan hilang ketika kita menjalankan go run main.go
lagi, Karena kita sudah memiliki file yang secara otomatis dibuat untuk menampung data yang kita inputkan.
Memodifikasi Program
Program yang kita buat disini tentunya jauh dari sempurna, kamu bisa mengubahnya sesuai keiginan. Misalnya tampilan pesan error yang mengganggu bisa kita hilangkan dengan menghapus kode yang di highligh dan nama variabel err
diganti underscore _
:
//Memuat data dari file
_ := data.MuatData()
- err := data.MuatData()
- if err != nil {
- fmt.Println("File belum dibuat atau tidak ditemukan")
- }
Underscore _
sebagai nama variabel digunakan untuk mengabaikan data yang di kembalikan oleh sebuah fungsi. Dalam kasus ini kamu juga bisa menulis hanya fungsinya saja:
//Memuat data dari file
data.MuatData()
- err := data.MuatData()
- if err != nil {
- fmt.Println("File belum dibuat atau tidak ditemukan")
- }