Thread overview
April 12, 2014

Torrent kütüphanesi yazıyorum ve her parçayı aşağıdaki işlev ile hash liyorum. Fakat bir sorunum var.

	static ubyte[20] hashPiece(std.stream.File handle, int n_piece, int size_piece){
		ubyte[] arr = new ubyte[size_piece];
		handle.seek(n_piece * size_piece, SeekPos.Set);
		auto read = handle.readBlock(arr.ptr, size_piece);
		return sha1Of(arr[0..read]);
	}

Şimdi 512 kb lık parçalara bölüp hashlenirken olurda eğer dosyanın son parça 512 den küçükse streamin üzerine diğer 2.dosya da yazılmalı hatta o da yetmezse 512 kb ı doldurmayı üçüncü bir dosyayı da streame dahil edip o şekilde hash almak gerek. Çoklu stream yapmak için mevcut bir şey var mı?

Zekeriya

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

April 13, 2014

Hocam şimdilik değişene kadar stream i kullanayım çünkü "seek" işlevi baya işime yarıyor. Sorunu da çözdüm nasıl çözdüğüme gelirsek eğer;

verileri okuduğum dizi istediğim boyuta gelirse hashliyorum gelmezse eğer sonraki okunan dosyayı aynı diziye yazıp boyutu kontrol ediyorum taa ki istenilen boyuta ulaşana kadar ve ulaşınca hashleme işlemini yapıyorum bu sayede gerek kalmadı. Beni biraz zorlayan (neyse ki çözdüm :) ama emin değilim ne kadar doğru ) bu dosya isimlerini mysql e yazıp gerekli parçaları oradan bulup çekmek.

std.stream.File handle = new std.stream.File();
btstring hashes;
ubyte[] arr = new ubyte[cast(size_t) sizePiece]; /// istenilen parça boyutunda dosyadan veri okumak için dizi aç
size_t apos; /// array pos
foreach(file; files){
	handle.open(file);/// sıradaki dosyayı aç
	while(!handle.eof){
		apos += handle.read(arr[apos..$]);
		if(apos == sizePiece){ /// istenilen boyuta ulaşmış mı?
			apos = 0;
			hashes ~= sha1Of(arr[0..cast(size_t) sizePiece]); /// veriyi hashle
		}
	}
	handle.close;
}

Veritabanından veri çekip dosyanın verisini yollama işlemi için ise

http://s24.postimg.org/4vwzh370l/torrentw.png

foreach(file; Tracker.db.query("Select * from torrentFiles where torrent = ? and start < ? order by start asc", torrentId, start + length)){
	auto s = to!ulong(file["start"]);
	handle.open(TorrentMainDirectory ~ r"\" ~ filePath ~ r"\" ~ file["file"]);
	handle.seek(start - s + readed ,SeekPos.Set);
	auto read = handle.readBlock(&arr[readed], length - readed);
	readed += read;
	handle.close();
	if(readed == length) break;
}

Burada sorgum sıkıntılı olabilir diye düşünüyorum ama bu kadar dosya da sorunsuz bir şekilde indirme yaptım. Fikrim şuydu ulaşılacak son adres mutlaka torent dosyalarının başlangıç adresinden büyük olmalı ve başlangıç adreslerine göre dosyaları sıralayayım dizi dolana kadar da sonraki dosyayı okumaya devam edeyim. Çalıştı da pek zorlamasam iyi gibi :) Bir hata sıkıntı çıkarsa artık ileride düzeltirim.

Birkaç gün belkide hafta ara vermek zorunda kaldım bu projeye ufak bir freelance iş aldım biraz para lazım oldu :)

Bu arada yardımlarınız için çok teşekkür ederim :) Sayenizde d dili değil sadece programlama üzerine de pek çok şey öğrendim iyi ki varsınız :)

Zekeriya

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

April 13, 2014

Öncelikle, std.stream.File yerine std.stdio.File'ı öneririm çünkü kalıcı olan o. (std.stream.File'ın yerine aralık kullanan yenisi gelecek deniyor ama bir türlü gelemedi. :) )

Buna hızlıca baktım ama hazır çözüm bilmiyorum. Belki std.stdio.File.byChunk ile parça parça okunur ve std.range.chain ile bu parçalar uç uca birleştirilir. Deneyecek enerjim yok. :( :)

Ali

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

April 13, 2014

Evet devamında kod var ama onu eklememişim :) Güzel yakaladınız

Zekeriya

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

April 13, 2014

Çözdüğüne sevindim. :) Son dosyanın son parçasını hash'lediğinden emin misin? En son durumda 'apos == sizePiece' olmamış olabilir.

Ali

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]