---
title: Arabellekler
source: 'https://academia.sh/tr/kurslar/nodejs/arabellekler'
course: 'Node.js Çalışma Zamanı'
language: tr
updated: '2026-08-17T18:09:50+00:00'
license: 'CC BY-SA 4.0'
---

# Arabellekler

Ham bayt dizisinin dizgiden farkı, sıfırlanmış ve sıfırlanmamış ayırma, görünüm ile kopya ayrımı, karakter sınırında bölünme sorunu ve ikili kayıt kodlama.

Önceki derste akıştan gelen parçaların türü `Buffer` göründü ve metne çevrilirken
kodlama adı elle verildi. Bir parçanın çok baytlı bir karakterin ortasından bölünmesi
durumunda ne olacağı ise sorulmadan bırakıldı.

Bu ders o soruyu yanıtlar. Konu, Bilgisayarlar Nasıl Çalışır kursundaki karakter
kodlamaları ve bayt sırası derslerinin doğrudan sürdürülmesidir: orada kurulan
kavramlar burada çalışan koda dönüşür.

## Bayt Dizisi Olarak Arabellek

**Arabellek (buffer)**, sabit uzunlukta ham bayt dizisini temsil eden nesnedir.
Dilin `Uint8Array` tipinden türer; dolayısıyla dizin erişimi, uzunluk ve yineleme
davranışı tipli dizilerle aynıdır. Üzerine eklenen şey, kodlama dönüşümleri ve
sayısal alan okuma-yazma yöntemleridir.

Dizgi ile arabellek arasındaki fark, ölçü biriminde görülür:

```js
// arabellek.mjs
const metin = 'sıcaklık';

const ab = Buffer.from(metin, 'utf8');
console.log('karakter sayisi :', metin.length);
console.log('bayt sayisi     :', ab.length, '=', Buffer.byteLength(metin, 'utf8'));
console.log('onaltilik       :', ab.toString('hex'));
console.log('Uint8Array mi   :', ab instanceof Uint8Array);
console.log('ilk uc bayt     :', [...ab.subarray(0, 3)]);
```

```sh
node arabellek.mjs
```

```
karakter sayisi : 8
bayt sayisi     : 10 = 10
onaltilik       : 73c4b163616b6cc4b16b
Uint8Array mi   : true
ilk uc bayt     : [ 115, 196, 177 ]
```

Sekiz karakterlik dizgi on bayt tuttu; `ı` harfi UTF-8'de iki bayt ile
(`c4 b1`) kodlanır ve sözcükte iki kez geçer. Bu ayrım, bir HTTP yanıtına
`Content-Length` başlığı yazarken önemlidir: başlığa yazılması gereken sayı bayt
sayısıdır, karakter sayısı değil. `Buffer.byteLength`, arabellek üretmeden bu sayıyı
verir.

## Ayırma, Görünüm ve Kopya

Arabellek üretmenin üç yolu vardır ve aralarındaki fark bellek davranışındadır.

```js
// arabellek-ayirma.mjs
const sifirli = Buffer.alloc(8);
console.log('alloc(8)          :', sifirli.toString('hex'));
console.log('allocUnsafe(8) boy:', Buffer.allocUnsafe(8).length);

// subarray bir kopya degil, ayni bellegin uzerine acilmis bir gorunumdur
const tam = Buffer.from('kenar-01', 'utf8');
const gorunum = tam.subarray(0, 5);
gorunum[0] = 'K'.charCodeAt(0);
console.log('gorunum degistirildi ->', tam.toString('utf8'));

// Kopya gerektiginde acikca istenir
const kopya = Buffer.from(tam.subarray(0, 5));
kopya[0] = 'x'.charCodeAt(0);
console.log('kopya degistirildi   ->', tam.toString('utf8'), '|', kopya.toString('utf8'));

// Parcalari tek arabellekte birlestirmek
const birlesik = Buffer.concat([Buffer.from('kenar'), Buffer.from('-'), Buffer.from('01')]);
console.log('concat               ->', birlesik.toString('utf8'), `(${birlesik.length} bayt)`);
```

```sh
node arabellek-ayirma.mjs
```

```
alloc(8)          : 0000000000000000
allocUnsafe(8) boy: 8
gorunum degistirildi -> Kenar-01
kopya degistirildi   -> Kenar-01 | xenar
concat               -> kenar-01 (8 bayt)
```

`Buffer.alloc`, istenen boyutta sıfırlanmış bellek verir. `Buffer.allocUnsafe`
sıfırlama adımını atlar ve daha hızlıdır; karşılığında arabellek, o bellekte daha
önce ne varsa onu içerir. İçeriği baştan sona yazmadan bu arabelleği kullanmak,
sürecin başka bir yerinde bulunan veriyi sızdırabilir. Kural: **arabelleği hemen ve
tamamen doldurmuyorsanız sıfırlanmış ayırma kullanın.**

Çıktının üçüncü satırı görünüm davranışını gösteriyor: `subarray` yeni bellek
ayırmaz, aynı belleğe açılmış bir pencere döndürür. Pencereye yazmak asıl arabelleği
değiştirir. Bu, kopyalamadan dilimleme olanağı verdiği için akış kodunda değerlidir;
farkında olunmadığında ise açıklaması zor hatalar üretir. Bağımsız bir kopya
gerektiğinde `Buffer.from` ile açıkça istenir.

`Buffer.concat`, parça listesini tek bir arabellekte birleştirir. Akıştan gelen
parçaları toplayıp sonunda tek metne çevirmenin standart yolu budur; parçaları
dizgiye çevirip birleştirmek, aşağıdaki soruna yol açar.

## Karakter Sınırında Bölünme

Bir parça, çok baytlı bir karakterin ortasında bitebilir. O parça tek başına metne
çevrilirse, yarım kalan karakter yerine değiştirme karakteri konur ve bilgi geri
dönüşsüz kaybolur.

```js
// arabellek-sinir.mjs
import { StringDecoder } from 'node:string_decoder';

const ab = Buffer.from('sıcaklık', 'utf8');   // 10 bayt
const parcaA = ab.subarray(0, 2);              // 'ı' harfinin ortasindan keser
const parcaB = ab.subarray(2);

console.log('dogrudan cozme :', parcaA.toString('utf8') + parcaB.toString('utf8'));

const cozucu = new StringDecoder('utf8');
console.log('cozucu ile     :', cozucu.write(parcaA) + cozucu.write(parcaB) + cozucu.end());
```

```sh
node arabellek-sinir.mjs
```

```
dogrudan cozme : s��caklık
cozucu ile     : sıcaklık
```

İlk satırdaki iki değiştirme karakteri, yarım kalan `ı` harfinin iki baytının ayrı
ayrı çözülmesinden doğdu. `node:string_decoder` modülündeki çözücü, tamamlanmamış
bayt dizisini kendinde tutar ve sonraki yazımla birleştirir; `end` çağrısı, elde
kalan eksik dizi varsa onu bildirir.

Bu, önceki dersteki `SatirBolucu` sınıfının gizli varsayımını açığa çıkarır. Orada
her parça doğrudan `toString('utf8')` ile çevrildi; ölçüm dosyası yalnızca ASCII
karakterler içerdiği için sorun görünmedi. Düğüm adlarında Türkçe karakter bulunan
bir veri kümesinde aynı kod bozulur. Doğru düzeltme, dönüştürücüde bir çözücü
tutmak ve `parca.toString('utf8')` yerine `cozucu.write(parca)` yazmaktır.

## İkili Kayıt Biçimi

Arabellek, sayısal alanları belirli genişlik ve bayt sırasıyla okuyup yazan yöntemler
sunar. Bu, ağ üzerinden gelen ikili bir protokolü ayrıştırmanın ve yer kazanmak için
kendi biçiminizi tanımlamanın yoludur.

Ölçüm kaydını altı bayta sığdıralım: bir bayt düğüm numarası, bir bayt metrik
numarası, dört bayt tek duyarlıklı kayan noktalı değer.

```js
// arabellek-ikili.mjs
// Bir olcumu 6 bayta sigdiran ikili bicim:
// [0] dugum no (uint8)  [1] metrik no (uint8)  [2..5] deger (float32, buyuk uclu)
function kodla(dugumNo, metrikNo, deger) {
  const ab = Buffer.alloc(6);          // sifirlanmis bellek
  ab.writeUInt8(dugumNo, 0);
  ab.writeUInt8(metrikNo, 1);
  ab.writeFloatBE(deger, 2);
  return ab;
}

function coz(ab) {
  return {
    dugumNo: ab.readUInt8(0),
    metrikNo: ab.readUInt8(1),
    deger: Number(ab.readFloatBE(2).toFixed(2)),
  };
}

const kayit = kodla(1, 0, 21.4);
console.log('ikili gosterim :', kayit.toString('hex'));
console.log('cozulmus kayit :', coz(kayit));

const kucukUclu = Buffer.alloc(4);
kucukUclu.writeFloatLE(21.4, 0);
console.log('kucuk uclu     :', kucukUclu.toString('hex'));
console.log('buyuk uclu     :', kayit.subarray(2).toString('hex'));

const metinBoyu = Buffer.byteLength(JSON.stringify({ dugum: 'kenar-01', metrik: 'sicaklik', deger: 21.4 }));
console.log(`metin gosterimi ${metinBoyu} bayt, ikili gosterim ${kayit.length} bayt`);
```

```sh
node arabellek-ikili.mjs
```

```
ikili gosterim : 010041ab3333
cozulmus kayit : { dugumNo: 1, metrikNo: 0, deger: 21.4 }
kucuk uclu     : 3333ab41
buyuk uclu     : 41ab3333
metin gosterimi 53 bayt, ikili gosterim 6 bayt
```

Yöntem adlarındaki `BE` ve `LE` sonekleri, Bilgisayarlar Nasıl Çalışır kursunda
tanıtılan büyük uçlu ve küçük uçlu yerleşimi seçer. Çıktının üçüncü ve dördüncü
satırları aynı sayının iki yerleşimini yan yana gösteriyor: bayt dizisi ters. Ağ
protokollerinde geleneksel seçim büyük uçlu yerleşimdir; bir biçim tanımlarken hangi
uçluluğun kullanıldığı yazılmalıdır, yoksa iki uç birbirinin verisini yanlış okur.

Son satır, ikili biçimin neden var olduğunu gösterir: aynı ölçüm metin olarak 53,
ikili olarak 6 bayt tutuyor. Karşılığında ikili biçim insan tarafından okunamaz,
kendini tanımlamaz ve alan eklendiğinde eski çözücüleri kırar. Bu ödünleşim
İnternet Nasıl Çalışır kursunda HTTP'nin metin tabanlı olması gerekçelendirilirken
tartışılmıştı; seçim, hacim ile incelenebilirlik arasındadır.

Değeri dört bayta sıkıştırmanın bir bedeli daha vardır. Tek duyarlıklı kayan noktalı
gösterim, yaklaşık yedi anlamlı ondalık basamak taşır; `21.4` değeri bu gösterimde
tam olarak temsil edilemez. Örnekte `toFixed(2)` ile yuvarlanmasının nedeni budur.
Ölçüm duyarlığı bu sınırın üstündeyse çift duyarlıklı yazma yöntemleri kullanılır.

Arabellek yöntemleri sınır denetimi yapar: dizinin dışına yazmaya çalışan bir çağrı
`RangeError` fırlatır. Bu, Bilgisayarlar Nasıl Çalışır kursunda anlatılan sınırsız
bellek erişimi sınıfındaki hataları çalışma zamanı düzeyinde engeller.

## Özet

- Arabellek, `Uint8Array` üzerine kurulmuş ham bayt dizisidir; karakter sayısı ile
  bayt sayısı çok baytlı kodlamalarda ayrışır ve protokol başlıklarına bayt sayısı
  yazılır.
- `Buffer.alloc` sıfırlanmış bellek verir; sıfırlamayı atlayan ayırma, tamamen
  doldurulmadığında eski bellek içeriğini sızdırır.
- `subarray` kopya değil görünüm döndürür; bağımsız kopya `Buffer.from` ile açıkça
  istenir.
- Çok baytlı bir karakter parça sınırında bölündüğünde doğrudan çözme veriyi bozar;
  `node:string_decoder` yarım baytları saklayarak bunu önler.
- Sayısal alanlar genişlik ve uçluluk seçilerek okunup yazılır; ikili biçim yer
  kazandırır, incelenebilirlik ve genişletilebilirlikten ödün verir.

## Sonraki Adım

Buraya kadar akışların olay yaydığından söz edildi ama olay düzeneğinin kendisi
açılmadı. Ölçüm toplayıcının bir sonraki adımı, veri geldiğinde ilgilenen tarafları
haberdar eden bir yapı gerektiriyor: eşik aşıldığında uyarı üreten, bozuk satırı
bildiren, kaynağın kapandığını duyuran bir düzenek. Sonraki ders bu düzeneğin temel
sınıfını — olay yayıcıyı — ele alır.
