Go Dilinde Concurrency

2,041 More

Projedeki Git Dosyaları Nasıl Silinir?

1 7,408 More

yTheme

4 2,626 More

Sunucu Güvenliği | SSH (Secure Shell) Kullanımı

2 2,041 More

Truemag

  • PHP
  • Golang
  • Laravel
  • Linux
  • SQL
  • SEO
  • WordPress
  • Diğer
    • Yazılım
    • Javascript
    • Css/XHtml/W3C
    • Genel
    • Tanıtım
    • Ajax
  • Home
  • ANASAYFA
  • HAKKIMDA
  • SPONSORLUK
  • ARŞİV
  • İLETİŞİM
  • BENİMLE ÇALIŞMAK İSTER MİSİNİZ?

Go ile Büyük JSON Dosyalarını Okuma

Her geçen gün tüm altyapısını Go’ya geçiren yeni bir firma duyuyoruz. Bunun sebebi de tahmin edersiniz ki Go’nun sunmuş olduğu kolaylıklar. İşte bunlardan birisi de JSON Data Streaming. Bu özellik hangi problemi çözüyor derseniz başlıkta da belirttiğim gibi büyük boyutlu JSON dosyalarınızı dertsiz tasasız okumaya yarıyor.

Problem Tanımı

Go ile normal bir şekilde JSON dosyası okumak gerçekten kolaydır. Elinizde bir JSON verisi bulunur. Buna karşılık gelen struct’ı (model) oluşturursunuz. Ardından Go’nun kendi json kütüphanesini json.Unmarshal() diyerek çalıştırırsınız. Böylece tüm json verisi memory’ye alınır ve uygulamanızda kullanılmaya hazırdır.

Peki uygulama içerisinde memory’de kullanıma hazır hale gelen JSON verisinin 4KB değil de 4GB olduğunu düşünelim! Bilgisayarın RAM miktarına falan girip konuyu uzatmaya gerek yok, böyle bir durumda uygulamanız eninde sonunda tabiri caizse patlayacaktır. Çünkü standart json.Unmarshal() fonksiyonu JSON verisini bir bütün halinde okur ancak büyük boyutlu dosyaları doğru şekilde okumanın yolu, JSON Data Streaming ile onu obje obje okumaktır.

Örnek JSON

Konuyu anlatabilmek için bize güzel bir JSON verisi lazım. Bunun için Star Wars filmindeki oyunculardan oluşan bir API’den faydalanalım. The Star Wars API (https://swapi.co/) sitesinin sunduğu şu uca (https://swapi.co/api/people/) tıklayarak JSON verimizi görebilirsiniz.

Tabi buradaki JSON verisi olduğu gibi kullanmadım çünkü sayfalama için Count, Next, Previous gibi şuan için ihtiyacımız olmayan özellikler vardı. Onun yerine çıktıyı, 87 isimin tamamından oluşan, dizi (array) şeklinde tek bir JSON haline getirdim. Bir kişi için genel yapı aşağıdaki gibidir. Tamamına yazının sonunda bağlantısı bulunan, bu yazı için hazırladığım örnek proje dosyalarından ulaşabilirsiniz.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
[
    {
        "name": "Luke Skywalker",
        "height": "172",
        "mass": "77",
        "hair_color": "blond",
        "skin_color": "fair",
        "eye_color": "blue",
        "birth_year": "19BBY",
        "gender": "male",
        "homeworld": "https://swapi.co/api/planets/1/",
        "films": [
            "https://swapi.co/api/films/2/",
            "https://swapi.co/api/films/6/",
            "https://swapi.co/api/films/3/",
            "https://swapi.co/api/films/1/",
            "https://swapi.co/api/films/7/"
        ],
        "species": [
            "https://swapi.co/api/species/1/"
        ],
        "vehicles": [
            "https://swapi.co/api/vehicles/14/",
            "https://swapi.co/api/vehicles/30/"
        ],
        "starships": [
            "https://swapi.co/api/starships/12/",
            "https://swapi.co/api/starships/22/"
        ],
        "created": "2014-12-09T13:50:51.644000Z",
        "edited": "2014-12-20T21:17:56.891000Z",
        "url": "https://swapi.co/api/people/1/"
    },
    ...
}

JSON’a Uygun Go Struct

Yukarıdaki yapıya uygun Go Struct’ını elle yazabiliriz ancak onun yerine JSON to Go sitesinden direk karşılığını görebiliriz. Buna göre struct’ımız şu şekildedir.

Go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
type People struct {
Name      string    `json:"name"`
Height    string    `json:"height"`
Mass      string    `json:"mass"`
HairColor string    `json:"hair_color"`
SkinColor string    `json:"skin_color"`
EyeColor  string    `json:"eye_color"`
BirthYear string    `json:"birth_year"`
Gender    string    `json:"gender"`
Homeworld string    `json:"homeworld"`
Films     []string  `json:"films"`
Species   []string  `json:"species"`
Vehicles  []string  `json:"vehicles"`
Starships []string  `json:"starships"`
Created   time.Time `json:"created"`
Edited    time.Time `json:"edited"`
URL       string    `json:"url"`
}

Normal Method ile JSON Okuma

JSON ve Struct’ımızı oluşturduktan sonra artık gerekli Go kodumuzu yazabiliriz. Aşağıdaki kod ile people.json dosyasındaki JSON verisini okuyup, kişilerin istediğimiz özelliğini ekrana yazdırabiliriz.

Go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
package main
 
import (
"encoding/json"
"fmt"
"io/ioutil"
"os"
"time"
)
 
var err error
 
type People struct {
Name      string    `json:"name"`
Height    string    `json:"height"`
Mass      string    `json:"mass"`
HairColor string    `json:"hair_color"`
SkinColor string    `json:"skin_color"`
EyeColor  string    `json:"eye_color"`
BirthYear string    `json:"birth_year"`
Gender    string    `json:"gender"`
Homeworld string    `json:"homeworld"`
Films     []string  `json:"films"`
Species   []string  `json:"species"`
Vehicles  []string  `json:"vehicles"`
Starships []string  `json:"starships"`
Created   time.Time `json:"created"`
Edited    time.Time `json:"edited"`
URL       string    `json:"url"`
}
 
func main() {
// JSON dosyasını açalım.
jsonDosya, err := os.Open("people.json")
if err != nil {
fmt.Println(err)
}
defer jsonDosya.Close()
 
// Dosya içeriğini okuyalım.
icerik, err := ioutil.ReadAll(jsonDosya)
if err != nil {
fmt.Println(err)
}
 
// Dosyadaki veriyi ayrıştırıp değişkenimize aktaralım.
var people []People
json.Unmarshal(icerik, &people)
 
// JSON verisindeki isimleri ekrana yazdıralım.
for _, person := range people {
fmt.Println(person.Name)
}
}

JSON Data Streaming Methodu ile Okuma

Büyük boyutlu dosyaları okumada temel olarak 2 fark bulunmaktadır.
1. json.Unmarshall() yerine, json.NewDecoder() kullanılır.
2. JSON’ı okuyup atayacağımız değişken dizi (array) değil, obje obje okuyacağımız için tekil struct olur.

Aynı JSON verisini obje obje okuyarak, her obje üzerinde işlem yapmak için aşağıdaki Go kodunu kullanabiliriz.

Go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
package main
 
import (
"encoding/json"
"fmt"
"io/ioutil"
"log"
"os"
"time"
)
 
var err error
 
type People struct {
Name      string    `json:"name"`
Height    string    `json:"height"`
Mass      string    `json:"mass"`
HairColor string    `json:"hair_color"`
SkinColor string    `json:"skin_color"`
EyeColor  string    `json:"eye_color"`
BirthYear string    `json:"birth_year"`
Gender    string    `json:"gender"`
Homeworld string    `json:"homeworld"`
Films     []string  `json:"films"`
Species   []string  `json:"species"`
Vehicles  []string  `json:"vehicles"`
Starships []string  `json:"starships"`
Created   time.Time `json:"created"`
Edited    time.Time `json:"edited"`
URL       string    `json:"url"`
}
 
func main() {
// JSON dosyasını açalım.
jsonDosya, err := os.Open("people.json")
if err != nil {
fmt.Println(err)
}
defer jsonDosya.Close()
 
dec := json.NewDecoder(jsonDosya)
 
// Başlangıç verisini ([) okuyalım
_, err = dec.Token()
if err != nil {
log.Println(err)
}
 
var person People
// Bu döngü okunacak bir sonraki obje var ise devam eder.
for dec.More() {
err = dec.Decode(&person)
if err != nil {
log.Println(err)
}
 
fmt.Println(person.Name)
}
 
// Kapanış verisini (]) okuyalım
_, err = dec.Token()
if err != nil {
log.Println(err)
}
}

Makale Dosyaları

Bu makale için hazırladığım örnek proje dosyalarına şu Github bağlantısından ulaşabilirsiniz:

https://github.com/yakuter/go-buyuk-json-okuma

Son Sözler

Uzun bir aradan sonra yeniden bir Go makalesi ile sizlerle bir araya geldik. Kısa bir JSON okumadan ziyade, büyük boyutlu dosyalara bir çözüm getirerek konuyu biraz da ihtiyacı karşılar hale getirmeye çalıştım. Umarım faydalı olmuştur.

Ara 3, 2019Erhan Yakut
Cloud Sunucu


hosting

Neden PHP’den Go’ya Geçtim?Flatfy, Bird ile Reddot Ödülünü Aldı!
You Might Also Like
 
Wordpres Çoklu Dil Desteği
 
Kurumsal Kimlik Nedir?
Erhan Yakut
1 year ago Golang1,204
Sponsorlar

sponsor

sponsor

sponsor

sponsor
Bağlantılar
  • Beyazıt Kölemen
  • Domatessuyu
  • Lezzetli Robot Tarifleri
  • Ofizzo
  • PHP Dersleri
  • Wordpress Hosting
Random Posts
Aşk Bu Olsa Gerek
WordPress’te Eklenti Kullanmadan Sayfalama
CentOS Firewall’da FTP Erişimini Açmak
Siteniz Sandbox’a Girmesin
WordPress İle Fan Sitesi
sdafasdf
Hakkımda

Bilişim Teknolojileri alanında içerik üretmek üzere oluşturulmuş olan Yakuter.com 2006 yılında Erhan Yakut tarafından hayata geçirilmiştir. devamını okuyun…

CLOUD SUNUCU DESTEĞİ
2006-2020 © Yakuter