Skip to content

Instantly share code, notes, and snippets.

@jutionck
Created August 2, 2023 04:37
Show Gist options
  • Save jutionck/ab54b350692ffb06e9fd1cba058b95a0 to your computer and use it in GitHub Desktop.
Save jutionck/ab54b350692ffb06e9fd1cba058b95a0 to your computer and use it in GitHub Desktop.

Create File

Pembuatan file dapat cukup mudah dilakukan di Go yaitu menggunakan package dari os, dengan fungsi os.Create() Langsung saja praktik, buat sebuah folder baru dengan nama file, agar lebih rapih buatlah folder baru didalamnya dengan nama data kemudian buat file baru didalam data dengan nama create_file.go yang isinya adalah sebagai berikut.

package data

import (
	"fmt"
	"os"

	"enigmacamp.com/basic-go/18-file/utils"
)

func CreateFile(fileName string) {
	// deteksi apakah file sudah ada
	// ini ganti aja sesuaikan (cek menggunakan pwd)
	path := "/Users/jutioncandrakirana/Documents/GitHub/enigma/GOLANG/golang-fundamental-sandbox/day-9/file/"
	fileName := "example.txt"
	filePath := path + fileName
	_, err := os.Stat(filePath)
	// buat file baru
	if os.IsNotExist(err) {
		file, err := os.Create(filePath)
		if err != nil {
			fmt.Println(err)
			return
		}

		defer file.Close()
	}

	fmt.Println("File dibuat...", fileName)
}

Penjelasan:

  • os.IsNotExist() -> untuk mendeteksi apakah file sudah dibuat atau belum.
  • os.Stat() -> mengembalikan 2 data, yaitu informasi tetang path yang dicari, dan error (jika ada).
  • os.Create() -> digunakan untuk membuat file pada path tertentu.

File yang baru terbuat statusnya adalah otomatis open, maka dari itu perlu untuk di-close menggunakan method file.Close() setelah file tidak digunakan lagi. Read File (os.ReadFile) File pada Go menggunakan sebuah pointer of object dari os.File Ketika pada materi sebelumnya (input) untuk menulis dan membaca adalah menggunakan os.Stdin dan os.Stdout. Isi dari db.dat adalah sebagai berikut:

Andi
Budi
Candra
Dodi
Erna

Selanjutnya buat file baru di data dengan nama get_file_os_open.go

package data

import (
	"bufio"
	"fmt"
	"io"
	"os"
)

func OpenFileWithOsOpen(fileName string) {
	inputFile, inputError := os.Open(fileName) // *os.File, error
	if inputError != nil {
		fmt.Printf("Terjadi masalah ketika membaca file\n" +
			"Apakah file ada?\n" +
			"Ada akses ?\n")
		return // keluar jika error
	}

	defer inputFile.Close()
	inputReader := bufio.NewReader(inputFile)
	for {
		inputString, readError := inputReader.ReadString('\n')
		if readError == io.EOF {
			return
		}
		fmt.Printf("Nama: %s", inputString)
	}
}

Penjelasan: io.EOF menandakan bahwa file yang sedang dibaca adalah baris terakhir isi atau end of file. Buat file index.go yang isinya adalah sebagai berikut

package main

import "enigmacamp.com/basic-go/18-file/data"

// set global var
var fileLocation = "db.dat"

func main() {
	// data.CreateFile(fileLocation)
	data.OpenFileWithOsOpen(fileLocation)
}

Jalankan program dan hasilnya adalah

Solusinya adalah, kita harus tahu benar letak atau posisi file itu dimana, untuk cek bisa menggunakan perintah pwd Jika sudah silahkan modifikasi menjadi

package main

import "enigmacamp.com/basic-go/18-file/data"

// set global var
var fileLocation = "/Users/jutioncandrakirana/Documents/GitHub/enigma/GOLANG/basic-programming-go/18-file/db.dat"

func main() {
	// data.CreateFile(fileLocation)
	data.OpenFileWithOsOpen(fileLocation)
}

Jalankan kembali

Read File (ioutil.ReadFile)

Selain menggunakan os.Open dari os Package dan io, kita bisa juga menggunakan package dari io/ioutil, buat file baru dengan nama get_file_io_readfile.go.

package data

import (
	"fmt"
	"io/ioutil"
	"os"
)

func OpenFileWithReadFile(fileName string) {
	buf, err := ioutil.ReadFile(fileName)
	if err != nil {
		fmt.Fprintf(os.Stderr, "File error: %s\n", err)
	}
	fmt.Printf("%s\n", string(buf))
}

Jangan gunakan ReadFile ketika mengakses sebuah file dengan ukuran besar, karena akan membutuhkan banyak memori ReadFile (os.OpenFile) os.OpenFile adalah fungsi yang memungkinkan kontrol lebih besar atas mode pembukaan file. Fungsi OpenFile mengambil nama file, satu atau lebih flag (secara logis OR-d bersama-sama menggunakan | bitwise OR operator jika lebih dari satu) dan izin file untuk digunakan. Beberapa flag yang dapat digunakan:

  • os.O_RDONLY: the read flag for read-only access
  • os.O_WRONLY: the write flag for write-only access
  • os.O_RDWR: the flag that provides both read and write access
  • os.O_CREATE: the create flag to create the file if it doesn’t exist
  • os.O_TRUNC: the truncate flag to truncate to size 0 if the file already exists

Saat membaca, izin file diabaikan sehingga kami dapat menggunakan nilai 0. Saat menulis, kami menggunakan izin file Unix standar 0666 (bahkan di Windows). Berikut contoh kodenya, buat file baru di data dengan nama get_file_os_open_file.go

package data

import (
	"fmt"
	"io"
	"os"
)

func OpenFileWithOpenFile(fileName string) {
	file, err := os.OpenFile(fileName, os.O_RDONLY, 0644)
	if err != nil {
		fmt.Println(err)
		return
	}

	defer file.Close()

	// Mendapatkan informasi ukuran file
	fileInfo, err := file.Stat()
	if err != nil {
		fmt.Println(err)
		return
	}
	fileSize := fileInfo.Size()

	// Membuat buffer sesuai dengan ukuran file
	buffer := make([]byte, fileSize)

	// Membaca isi file ke dalam buffer
	_, err = file.Read(buffer)
	if err != nil {
		fmt.Println(err)
		return
	}

	// Menampilkan isi file
	fmt.Println(string(buffer))
}

Panggil fungsi diatas pada main()

package main

import "enigmacamp.com/basic-go/18-file/data"

// set global var
var fileLocation = "/Users/jutioncandrakirana/Documents/GitHub/enigma/GOLANG/basic-programming-go/18-file/db.dat"

func main() {
	// data.CreateFile(fileLocation)
	// data.OpenFileWithOsOpen(fileLocation)
	// data.OpenFileWithReadFile(fileLocation)
	data.OpenFileWithOpenFile(fileLocation)
}
Write (WriteString)
Buat file baru di folder data dengan nama writing_to_file.go
package data

import (
	"fmt"
	"os"
)

func WriteToFileWithString(filePath string, data string) {
	file, err := os.OpenFile(filePath, os.O_CREATE|os.O_WRONLY, 0644)
	if err != nil {
		fmt.Printf("Gagal membuka file: %v\n", err)
		os.Exit(1)
	}

	_, err = file.WriteString(data + "\n")
	if err != nil {
		fmt.Printf("Gagal menulis ke file: %v\n", err)
		os.Exit(1)
	}

	err = file.Sync()
	if err != nil {
		fmt.Printf("Gagal sinkronisasi ke file: %v\n", err)
		os.Exit(1)
	}
}

Pada main()

package main

import "enigmacamp.com/basic-go/18-file/data"

// set global var
var fileLocation = "/Users/jutioncandrakirana/Documents/GitHub/enigma/GOLANG/basic-programming-go/18-file/db.dat"

func main() {
	// data.CreateFile(fileLocation)
	// data.OpenFileWithOsOpen(fileLocation)
	// data.OpenFileWithReadFile(fileLocation)
	// data.OpenFileWithOpenFile(fileLocation)
	data.WriteToFileWithString(fileLocation, "Jution")
}

Kode diatas hanya untuk inputan sekali, jika mencoba untuk input lagi isi file lama maka akan ter-replace Agar tidak ter-replace maka rubah pada bagian ini outputFile, outputError := os.OpenFile(fileName, os.O_APPEND|os.O_WRONLY, 0644) Jenis dan Tipe Menulis ke File Disini akan mencontohkan beberapa tipe penulisan ke sebuah file yaitu plain text, csv dan json. Contoh data dalam bentuk CSV

nama,usia,alamat
Jution,25,Jakarta
Fadli,28,Bandung

Contoh data dalam bentuk JSON.

[
    {
        "id": "001",
        "nama": "Jution Candra Kirana"
    }
]

Write to File CSV

// untuk [][]string bisa ganti dengan Struct (bisa berikan struct tag csv)

func WriteToFileCSV(filePath string, data [][]string) {
	file, err := os.OpenFile(filePath, os.O_CREATE|os.O_WRONLY, 0644)
	if err != nil {
		fmt.Printf("Gagal membuka file: %v\n", err)
		os.Exit(1)
	}
	writer := csv.NewWriter(file)
	writer.WriteAll(data)
	writer.Flush()

	fmt.Println("Data berhasil disimpan dalam file example.csv")
}

Sehingga pada main.

// CSV
data := [][]string{
	{"nama", "usia", "alamat"},
	{"Jution", "25", "Jakarta"},
	{"Fadli", "28", "Bandung"},
}
fileCSV := "/Users/jutioncandrakirana/Documents/GitHub/enigma/GOLANG/golang-fundamental-sandbox/day-9/file/example.csv"
handler.WriteToFileCSV(fileCSV, data)

Terdapat kesalahan saat penambahan data, harusnya ketika kita membuat data baru kita tidak perlu menuliskan header seperti nama, usia, alamat. Kode sebelumnya juga ketika data ada yang baru lagi maka akan ter-replace. Perbaikan kode adalah sebagai berikut.

func WriteToFileCSV(filePath string, data [][]string) {
	file, err := os.OpenFile(filePath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
	if err != nil {
		fmt.Printf("Gagal membuka file: %v\n", err)
		os.Exit(1)
	}
	defer file.Close()

	writer := csv.NewWriter(file)
	if fileStat, _ := file.Stat(); fileStat.Size() == 0 {
		writer.Write([]string{"nama", "usia", "alamat"})
	}
	writer.WriteAll(data)
	writer.Flush()

	fmt.Println("Data berhasil disimpan dalam file", filePath)
}

Pada main menjadi berikut.

package main

import (
	"github.com/jutionck/golang-fundamental-sandbox/day-9/file/handler"
)

func main() {
	fileCSV := "/Users/jutioncandrakirana/Documents/GitHub/enigma/GOLANG/golang-fundamental-sandbox/day-9/file/example.csv"

	newPenduduk := [][]string{
		{"Jution", "25", "Bandung"},
		{"Fadli", "22", "Jakarta"},
	}
	handler.WriteToFileCSV(fileCSV, newPenduduk)
}

Jalankan program.

Write to File JSON

// untuk []string bisa ganti dengan Struct (bisa berikan struct tag `json`)
func WriteToFileJSON(filePath string, data []map[string]string) {
	jsonData, err := json.MarshalIndent(data, "", "    ")
	if err != nil {
		fmt.Println(err)
		return
	}

	err = ioutil.WriteFile(filePath, jsonData, 0644)
	if err != nil {
		fmt.Println(err)
		return
	}

	fmt.Println("Data berhasil disimpan dalam file", filePath)
}

Sehingga pada main.

dataJSON := []map[string]string{
	{"nama": "Jution", "usia": "25", "alamat": "Jakarta"},
	{"nama": "Fadli", "usia": "28", "alamat": "Bandung"},
}
fileJSON := "/Users/jutioncandrakirana/Documents/GitHub/enigma/GOLANG/golang-fundamental-sandbox/day-9/file/example.json"
handler.WriteToFileJSON(fileJSON, dataJSON)

Terdapat kesalahan pada saat menambahkan data JSON, karena ketika kita mencoba memasukkan data baru maka data lama akan ter-replace. Kenapa seperti itu karena kita tidak melakukan pengecekan terlebih dahulu apakah data sudah ada atau tidak. Perbaikan yang dapat dilakukan adalah sebagai berikut.

func WriteToFileJSON(filePath string, data map[string]string) {
	var ps []map[string]string
	penduduk, err := ioutil.ReadFile(filePath)
	if err != nil {
		fmt.Printf("Gagal membaca file: %v\n", err)
		os.Exit(1)
	}

	if len(penduduk) != 0 {
		err = json.Unmarshal(penduduk, &ps)
		if err != nil {
			fmt.Printf("Gagal membaca file: %v\n", err)
			os.Exit(1)
		}
	}

	ps = append(ps, data)

	jsonData, err := json.MarshalIndent(ps, "", "    ")
	if err != nil {
		fmt.Println(err)
		return
	}

	err = ioutil.WriteFile(filePath, jsonData, 0644)
	if err != nil {
		fmt.Println(err)
		return
	}

	fmt.Println("Data berhasil disimpan dalam file", filePath)
}

Sekarang pada main menjadi berikut.

package main

import (
	"github.com/jutionck/golang-fundamental-sandbox/day-9/file/handler"
)

func main() {
	fileJSON := "/Users/jutioncandrakirana/Documents/GitHub/enigma/GOLANG/golang-fundamental-sandbox/day-9/file/example.json"

	newPenduduk := map[string]string{
		"nama":   " Jution",
		"usia":   " 25",
		"alamat": " Jakarta",
	}
	handler.WriteToFileJSON(fileJSON, newPenduduk)
}

Jalankan lagi program.

Membaca File dari CSV & JSON

Untuk membaca file .csv

func ReadFileCSV(filePath string) {
	file, err := os.OpenFile(filePath, os.O_RDONLY, os.ModePerm)
	if err != nil {
		fmt.Println("Error:", err)
		return
	}
	defer file.Close()

	reader := csv.NewReader(file)
	records, err := reader.ReadAll()
	if err != nil {
		fmt.Println("Error:", err)
		return
	}

	// Ambil baris pertama sebagai header
	header := records[0]

	// Buat slice untuk menampung data
	var data []map[string]string

	// Loop untuk setiap baris data (mulai dari baris kedua)
	for i := 1; i < len(records); i++ {
		row := records[i]
		m := make(map[string]string)
		for j := 0; j < len(header); j++ {
			m[header[j]] = row[j]
		}
		data = append(data, m)
	}

	fmt.Println(data)
}

Pastikan file .csv ada. Disini masih menggunakan file yang sebelumnya di atas. Jika kita lihat isi dari file .csv adalah seperti berikut.

nama,usia,alamat
Jution,25,Jakarta
Fadli,28,Bandung

Jika sudah kita panggil funciton read csv yang sudah dibuat pada func main

fileCSV := "/Users/jutioncandrakirana/Documents/GitHub/enigma/GOLANG/golang-fundamental-sandbox/day-9/file/example.csv"
// Read file CSV
handler.ReadFileCSV(fileCSV)

Sekarang kita akan membaca file dari .json Pastikan file sudah ada dan ada isinya, disini file .json isinya seperti berikut.

[
  {
    "alamat": "Jakarta",
    "nama": "Jution",
    "usia": "25"
  },
  {
    "alamat": "Bandung",
    "nama": "Fadli",
    "usia": "28"
  }
]

Untuk kode membaca data json seperti berikut.

func ReadFileJSON(filePath string) {
	file, err := ioutil.ReadFile(filePath)
	if err != nil {
		fmt.Println("Error reading JSON file:", err)
		return
	}

	// Dekode file JSON ke dalam map[string]interface{}
	var data []map[string]interface{}
	if err := json.Unmarshal(file, &data); err != nil {
		fmt.Println("Error decoding JSON file:", err)
		return
	}

	// Tampilkan data dari map
	for _, item := range data {
		fmt.Printf("Nama: %s\n", item["nama"])
		fmt.Printf("Usia: %s\n", item["usia"])
		fmt.Printf("Alamat: %s\n", item["alamat"])
	}
}

Setelah itukita panggil di main.

// JSOn
fileJSON := "/Users/jutioncandrakirana/Documents/GitHub/enigma/GOLANG/golang-fundamental-sandbox/day-9/file/example.json"

// Read file JSON
handler.ReadFileJSON(fileJSON)

Jalankan program.

Merubah Data Pada File JSON

Praktik ini melanjutkan untuk praktik write json dan read json. Kebutuhan update sangat diperlukan ketika kita sudah mempunyai data pada json dan ingin merubah. Kode berikut adalah cara untuk melakukan perubah data, tetapi sebelum itu kita akan mencoba sedikit modifikasi, sebelumnya kita menggunakan sebuah map sekarang kita coba ubah menjadi sebuah struct. Buat struct baru dengan nama Penduduk misalnya.

type Penduduk struct {
    Nama string
    Usia string
    Alamat string
}

Pada struct kita bisa memberikan sebuah tag, karena kita akan membaca sebuah file JSON maka bisa kita ubah struct di atas dengan menambahkan struct tag json. Jaidnya seperti ini.

type Penduduk struct {
    Nama   string `json:"nama"`
    Usia   string `json:"usia"`
    Alamat string `json:"alamat"`
}

Sekarang ubah function ReadJSON sebelumnya dengan ini.

func ReadFileJSON(filePath string) {
	file, err := ioutil.ReadFile(filePath)
	if err != nil {
		fmt.Println("Error reading JSON file:", err)
		return
	}

	// Dekode file JSON ke dalam map[string]interface{}
	var data []model.Penduduk
	if err := json.Unmarshal(file, &data); err != nil {
		fmt.Println("Error decoding JSON file:", err)
		return
	}

	for _, item := range data {
		fmt.Printf("Nama: %s\n", item.Nama)
		fmt.Printf("Usia: %s\n", item.Usia)
		fmt.Printf("Alamat: %s\n", item.Alamat)
		fmt.Println()
	}
}

Kita coba dahulu pada main.

package main

import "github.com/jutionck/golang-fundamental-sandbox/day-9/file/handler"

func main() {
	fileJSON := "/Users/jutioncandrakirana/Documents/GitHub/enigma/GOLANG/golang-fundamental-sandbox/day-9/file/example.json"
	// Read file JSON
	handler.ReadFileJSON(fileJSON)
}

Kita jalankan program.

Lanjut, sekarang kita mencoba untuk merubah data yang sudah ada, misalnya kita akan merubah data dengan data Jution. Disini menggunakan nama karena di struct kita tidak terdapat id, sebaiknya kita memberikan id sebagai unique value. Kode nya adalah sebagai berikut.

func UpdateDataJSON(filePath string, newData interface{}) error {
	// Baca file JSON
	jsonFile, err := os.OpenFile(filePath, os.O_RDONLY, 0644)
	if err != nil {
		return err
	}
	defer jsonFile.Close()

	byteValue, err := ioutil.ReadAll(jsonFile)
	if err != nil {
		return err
	}

	// Parse data JSON ke dalam slice of struct
	var people []model.Penduduk
	err = json.Unmarshal(byteValue, &people)
	if err != nil {
		return err
	}

	// convert interface{} ke struct
	newDataConvert := newData.(model.Penduduk)

	// Ubah data di dalam slice of struct
	for i, v := range people {
		if v.Nama == newDataConvert.Nama {
			people[i] = newDataConvert
			break
		}
	}

	// Tulis kembali data ke dalam file JSON
	updatedData, err := json.MarshalIndent(people, "", "  ")
	if err != nil {
		return err
	}

	err = ioutil.WriteFile(filePath, updatedData, 0644)
	if err != nil {
		return err
	}

	fmt.Println("Data berhasil diupdate")
	return nil
}

Pada main untuk merubah data seperti ini.

package main

import (
	"fmt"

	"github.com/jutionck/golang-fundamental-sandbox/day-9/file/handler"
	"github.com/jutionck/golang-fundamental-sandbox/day-9/file/model"
)

func main() {
	fileJSON := "/Users/jutioncandrakirana/Documents/GitHub/enigma/GOLANG/golang-fundamental-sandbox/day-9/file/example.json"

	// Read file JSON
	handler.ReadFileJSON(fileJSON)

	// Ubah Data
	updateData := model.Penduduk{
		Nama:   "Jution",
		Usia:   "25",
		Alamat: "Lampung",
	}
	err := handler.UpdateDataJSON(fileJSON, updateData)
	if err != nil {
		fmt.Println(err)
		return
	}
}

Sekarang data jution berubah.

Menghapus Data Pada File JSON

Setelah berhasil merubah data, sekarang kita akan mencoba menghapus data pada file JSON. Kode nya adalah sebagai berikut.

func RemoveDataJSON(filePath string, nama string) {
	file, err := os.OpenFile(filePath, os.O_RDWR, 0644)
	if err != nil {
		log.Fatal(err)
	}
	defer file.Close()

	// membaca isi file JSON
	data, err := ioutil.ReadAll(file)
	if err != nil {
		log.Fatal(err)
	}

	// mengubah data JSON menjadi slice of struct
	var people []model.Penduduk
	err = json.Unmarshal(data, &people)
	if err != nil {
		log.Fatal(err)
	}

	// hapus data dengan ID 2
	for i, person := range people {
		if person.Nama == nama {
			people = append(people[:i], people[i+1:]...)
			break
		}
	}

	// encode data ke JSON
	newData, err := json.MarshalIndent(people, "", "    ")
	if err != nil {
		log.Fatal(err)
	}

	// menulis data ke file JSON
	err = ioutil.WriteFile(filePath, newData, 0644)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println("Data berhasil dihapus dari file JSON")
}

Karena sekali lagi kita tidak ada Id pada struct maka kita gunakan sebuah nama. Pada main jadi seperti ini.

package main

import (
	"fmt"

	"github.com/jutionck/golang-fundamental-sandbox/day-9/file/handler"
	"github.com/jutionck/golang-fundamental-sandbox/day-9/file/model"
)

func main() {
	fileJSON := "/Users/jutioncandrakirana/Documents/GitHub/enigma/GOLANG/golang-fundamental-sandbox/day-9/file/example.json"
	// Hapus Data
	nama := "Jution"
	handler.RemoveDataJSON(fileJSON, nama)
}

Jalankan dan data berhasil di hapus.

Delete a file

Buat file baru di dalam folder data bernama delete_file.go

package data

import (
	"fmt"
	"os"

	"enigmacamp.com/basic-go/18-file/utils"
)

func DeleteFile(fileName string) {
	err := os.Remove(fileName)
	if utils.IsError(err) {
		return
	}

	fmt.Println("File berhasil di hapus")
}

Pada main()

package main

import "enigmacamp.com/basic-go/18-file/data"

// set global var
var fileLocation = "/Users/jutioncandrakirana/Documents/GitHub/enigma/GOLANG/basic-programming-go/18-file/db.dat"

func main() {
	// data.CreateFile(fileLocation)
	// data.OpenFileWithOsOpen(fileLocation)
	// data.OpenFileWithReadFile(fileLocation)
	// data.OpenFileWithOpenFile(fileLocation)
	// data.WriteToFile(fileLocation, "Jution")
	data.DeleteFile(fileLocation)
}

File Handler

Digunakan untuk kebutuhan membuat aplikasi sederhana menggunakan file. Kode ini bisa disimpan kedalam folder utils kemudian beri nama file_handler.go.

package utils

import (
	"fmt"
	"io/ioutil"
	"os"
)

func OpenFile(filepath string) (*os.File, error) {
	file, err := os.OpenFile(filepath, os.O_APPEND|os.O_WRONLY, 0644)
	if err != nil {
		return nil, fmt.Errorf("failed to open file: %v", err)
	}
	return file, nil
}

func CloseFile(file *os.File) error {
	err := file.Close()
	if err != nil {
		return fmt.Errorf("failed to close file: %v", err)
	}
	return nil
}

func ReadFile(filepath string) ([]byte, error) {
	fileInfo, err := os.Stat(filepath)
	if err != nil {
		return nil, fmt.Errorf("failed to read file info: %v", err)
	}

	var data []byte
	// Mengecek ukuran file menggunakan fileInfo.Size()
	if fileInfo.Size() == 0 {
		// Jika ukuran file sama dengan 0, 
		// maka fungsi akan mengembalikan byte slice kosong ([]byte{}).
		data = []byte{}
	} else {
		data, err = ioutil.ReadFile(filepath)
		if err != nil {
			return nil, fmt.Errorf("failed to read file: %v", err)
		}
	}

	return data, nil
}

func WriteToFile(file *os.File, data []byte) error {
	// Perbedaan utama antara file.Write dan
	// ioutil.WriteFile adalah pada cara penggunaannya. 
	// Jika kita ingin menambahkan data ke akhir file tanpa menimpa data yang sudah ada, kita harus menggunakan file.Write. 
	// Namun, jika kita ingin menulis data baru ke file dan menimpa data yang sudah ada, kita harus menggunakan ioutil.WriteFile.
	_, err := file.Write(data)
	if err != nil {
		return fmt.Errorf("failed to write to file: %v", err)
	}
	return nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment