1. İşletim Sistemi Kütüphanesinin Temelleri
Golang'daki os
paketi, işletim sistemi işlevleri için platformdan bağımsız bir arayüz sağlar. Bir sonraki adımda, dosya açma, kapatma, okuma, yazma, dosya özniteliklerini elde etme ve ayarlama gibi işlemleri gerçekleştirmek için os
paketini nasıl kullanacağımızı tartışacağız.
1.1 Dosya Açma ve Kapatma
Go dilinde, bir dosyayı açmak için os.Open
işlevini kullanabilirsiniz. Bu işlev, bir *os.File
nesnesi ve bir hata döndürecektir. Dosya açıldıktan sonra okuma, yazma ve diğer işlemleri gerçekleştirebilirsiniz. İşlemler tamamlandıktan sonra, dosyayı kapatmak ve ilgili kaynakları serbest bırakmak için file.Close
çağrısını yapmalısınız.
İşte bir dosyanın açılmasının örneği:
package main
import (
"fmt"
"os"
)
func main() {
// Mevcut dizindeki test.txt dosyasını aç
file, err := os.Open("test.txt")
if err != nil {
// Dosya açma hatasıyla başa çık
fmt.Println("Dosya açılırken hata oluştu:", err)
return
}
// Dosyanın nihayetinde kapatılmasını sağlamak için defer deyimini kullan
defer file.Close()
// Dosya işlemleri...
fmt.Println("Dosya başarıyla açıldı")
}
Yukarıdaki kodda, defer
deyimini kullanarak file.Close
'ın mutlaka çalıştırılmasını sağlıyoruz. Bu, Go dilinde kaynak temizliği için yaygın bir uygulamadır.
1.2 Dosya Okuma ve Yazma İşlemleri
os.File
türü, dosya okuma ve yazma işlemleri için Read
ve Write
yöntemlerine sahiptir. Read
yöntemi, verileri dosyadan bir byte dilimine okur, Write
yöntemi ise bir byte diliminden dosyaya veri yazar.
Aşağıdaki örnek, bir dosyadan okuma ve bir dosyaya yazma işlemlerini nasıl gerçekleştireceğimizi göstermektedir:
package main
import (
"fmt"
"os"
)
func main() {
// Dosyayı aç
file, err := os.OpenFile("test.txt", os.O_RDWR, 0644)
if err != nil {
fmt.Println("Dosya açılırken hata oluştu:", err)
return
}
defer file.Close()
// Dosyaya içerik yaz
mesaj := []byte("Merhaba, Gophers!")
_, yazımHatasi := file.Write(mesaj)
if yazımHatasi != nil {
fmt.Println("Dosyaya yazılırken hata oluştu:", yazımHatasi)
return
}
// Dosyayı başından oku
file.Seek(0, 0)
buffer := make([]byte, len(mesaj))
_, okumaHatasi := file.Read(buffer)
if okumaHatasi != nil {
fmt.Println("Dosya okunurken hata oluştu:", okumaHatasi)
return
}
fmt.Println("Dosya içeriği:", string(buffer))
}
Bu örnekte, os.Open
yerine os.OpenFile
'ı kullanıyoruz. os.OpenFile
işlevi, dosyayı açarken kullanılacak modu ve izinleri belirtmenize olanak tanır. Yukarıdaki örnekte, os.O_RDWR
bayrağı kullanılır, bu da dosyanın okuma-yazma modunda açılacağı anlamına gelir.
1.3 Dosya Özellikleri ve İzinler
Dosya durumu bilgilerine erişmek ve değiştirmek için os
paketinden fonksiyonları kullanabilirsiniz. os.Stat
veya os.Lstat
kullanarak os.FileInfo
arabirimini elde edebilirsiniz, bu da dosya hakkında boyut, izinler, değiştirme zamanı ve daha fazla bilgi sağlar.
İşte dosya durumunu elde etmenin bir örneği:
package main
import (
"fmt"
"os"
)
func main() {
dosyaBilgisi, hata := os.Stat("test.txt")
if hata != nil {
fmt.Println("Dosya bilgileri alınırken hata oluştu:", hata)
return
}
// Dosya boyutunu yazdır
fmt.Printf("Dosya boyutu: %d byte\n", dosyaBilgisi.Size())
// Dosya izinlerini yazdır
fmt.Printf("Dosya izinleri: %s\n", dosyaBilgisi.Mode())
}
Dosya adını değiştirmek veya dosyanın izinlerini değiştirmeniz gerekiyorsa, dosyayı yeniden adlandırmak için os.Rename
veya dosyanın izinlerini değiştirmek için os.Chmod
kullanabilirsiniz.
package main
import (
"fmt"
"os"
)
func main() {
// Dosya izinlerini salt okunur yap
hata := os.Chmod("test.txt", 0444)
if hata != nil {
fmt.Println("Dosya izinleri değiştirilirken hata oluştu:", hata)
return
}
// Dosyayı yeniden adlandır
yenidenAdlandirmaHata := os.Rename("test.txt", "yenidenAdlandirilmis.txt")
if yenidenAdlandirmaHata != nil {
fmt.Println("Dosya yeniden adlandırılırken hata oluştu:", yenidenAdlandirmaHata)
return
}
fmt.Println("Dosya işlemleri başarılı")
}
Burada, test.txt
dosyasının izinlerini salt okunur yapar ve ardından dosyayı yenidenAdlandirilmis.txt
olarak yeniden adlandırırız. Dosya izinlerini değiştirirken, yanlış izin ayarları erişilemeyen dosyalara yol açabileceği için dikkatli olun.
2. IO Kütüphanesinin Temel Kullanımı
Go dilinde io
kütüphanesi, temel giriş/çıkış (I/O) işlemleri için temel arabirimler sağlar. io
kütüphanesinin tasarımı basitlik ve düzenli arabirim prensiplerini takip eder, farklı türdeki I/O işlemleri için dosya okuma/yazma, ağ iletişimi, veri önbelleği ve daha fazlası için temel desteği sağlar.
2.2 Okuyucu ve Yazıcı Arabirimlerinin Kullanımı
io.Reader
ve io.Writer
, bir nesnenin okuma ve yazma işlemlerini belirtmek için kullanılan temel arabirimlerdir. Dosyalar, ağ bağlantıları ve önbellek gibi farklı türler tarafından uygulanırlar.
io.Reader
io.Reader
arabirimine ait Read
yöntemi bulunmaktadır:
Read(p []byte) (n int, err error)
Bu yöntem, io.Reader
içinden p
'ye kadar olan veriyi p
'ye kadar okur. Okunan bayt sayısını n
(0 <= n
<= len(p
)) ve karşılaşılan herhangi bir hatayı döndürür.
Örnek kod:
package main
import (
"fmt"
"io"
"strings"
)
func main() {
r := strings.NewReader("Merhaba, Dünya!")
buf := make([]byte, 4)
for {
n, hata := r.Read(buf)
if hata == io.EOF {
break
}
fmt.Printf("Okunan baytlar: %d, İçerik: %s\n", n, buf[:n])
}
}
Bu örnekte, bir string'den veri okumak için strings.NewReader
oluşturuyor ve ardından veriyi 4 baytlik parçalar halinde okuyoruz.
io.Writer
io.Writer
arabirimi, Write
yöntemine sahiptir:
Write(p []byte) (n int, err error)
Bu yöntem, p
'den gelen veriyi altta yatan veri akışına yazar ve yazılan bayt sayısını ve karşılaşılan herhangi bir hatayı döndürür.
Örnek kod:
package main
import (
"fmt"
"os"
)
func main() {
data := []byte("Merhaba, Dünya!\n")
n, hata := os.Stdout.Write(data)
if hata != nil {
panic(hata)
}
fmt.Printf("Yazılan baytlar: %d\n", n)
}
Bu örnek, basit bir metni standart çıkış os.Stdout
'a yazarak, io.Writer
'ın bir uygulaması olarak hareket eder.
2.3 Gelişmiş Okuma/Yazma Fonksiyonları
io
paketi, veri kopyalama ve belirli miktarda veri okuma gibi yaygın görevleri kolaylaştırabilen bazı gelişmiş fonksiyonlar sağlar.
Kopyalama Fonksiyonu
io.Copy
, ara belleğe gerek olmadan bir io.Reader
dan bir io.Writer
a direkt olarak veri kopyalamak için kullanışlı bir yöntemdir.
Örnek kod:
package main
import (
"io"
"os"
"strings"
)
func main() {
r := strings.NewReader("Basit kopyalama işlemi örneği")
_, err := io.Copy(os.Stdout, r)
if err != nil {
panic(err)
}
}
Bu örnekte bir string'i doğrudan standart çıktıya kopyalıyoruz.
ReadAtLeast Fonksiyonu
io.ReadAtLeast
fonksiyonu, belirtilen miktarda verinin dönmeden önce bir io.Reader
dan en az o miktarda verinin okunmasını sağlar.
func ReadAtLeast(r Reader, buf []byte, min int) (n int, err error)
Örnek kod:
package main
import (
"fmt"
"io"
"strings"
)
func main() {
r := strings.NewReader("Go Dilindeki Türkçe Websitesi")
buf := make([]byte, 14)
n, err := io.ReadAtLeast(r, buf, 14)
if err != nil {
fmt.Println(err)
}
fmt.Printf("%s\n", buf[:n])
}
Bu örnekte io.ReadAtLeast
, buf
içine en az 14 byte veri okumayı denemektedir.
Bu gelişmiş okuma/yazma fonksiyonları, I/O ile ilgili görevleri daha verimli bir şekilde ele almanızı sağlar ve daha karmaşık program mantığının temelini oluşturmak için sağlam bir temel sunar.