2010-06-04 28 views
5

Daha sonra temizlik yapmakla görevlendirilmiş bir uygulamam var. Uygulamanın kendisi nispeten basittir - bir SQL sorgusu çalıştırır, bir web servisi tüketir ve sonuçları bir günlük dosyasına gönderir. Benim işim, uygulama onlarla yapıldıktan sonra dosyaları NAS'ımıza arşivlemektir. Dosyaları, yalnızca onlarla bitene kadar kilitler, böylece küçük bir karmaşıklık ekler. Ayrıca uygulamaya, sadece günlüklere dokunmama izin verilmiyor. Neyse başvurum oldukça basittir: Dosya açılabilirTers Akış Okuyucusu

  1. Kontrol if (IOException yakalamak) ve hiçbir istisnası atılır eğer bir bool [] erişilebileceğini onu işaretleyin.
  2. Doğru olarak işaretlenmiş dosya dizisini inceleyerek, dosyanın her satırını ReadLine yöntemini kullanarak bir StreamReader'a okuyun. Uygulama bazen hıçkırdığı ve bitmediği için, dosyanın tamamlanıp tamamlanmadığını söylemek için IOException'ı kullanamıyorum - aslında metni ayrıştırmak zorundayım.
  3. Bildiri tamamlandığını gösteren metin bulunursa, dosyayı sıkıştırın, arşivlenmiş dosyayı NAS'a yükleyin ve orijinali silin.

Kodum işe yarıyor, sadece çok zaman alıyor (günlük dosyaları her biri 500 MB civarındadır). İyileştirme konusundaki düşüncelerim, aramamın üst kısımdan ziyade dosyanın alt kısmından başlamasını gerektiriyordu, ancak StreamReader böyle bir yöntemi desteklemiyor. Ben ReadToEnd yöntemini kullanamıyorum ve sonra bir ters bellek istisnası attı çünkü okundu. Günlük dosyasının ayrıştırılmasını hızlandırabilmem için bir fikrin var mı?

+0

gibi koduyla yapılabilir? zip yapma, NAS'a kopyalama, silme veya dosyayı açmaya çalışırken (ve büyük olasılıkla başarısız olan) tüm bu şeyler bir süre alabiliyormuş gibi geliyor – luke

+0

Olası dupe: http://stackoverflow.com/questions/452902/how-to-read -a-metin-dosya-ters-ile-iterator-in-c –

+1

İyi soru. Evet, kesinlikle yürütmenin zaman alıcı kısmı olan ayrıştırma. Kodu ayrı işlevlere ayırdım ve her birine kırılma noktaları koydum. Sıkıştırma yaklaşık 30 - 45 saniye sürüyor, ayrıştırma iki saatten fazla sürebilir. – monkeyninja

cevap

6

İşin bitip bitmediğini belirlemek için dosyanın sonunda tek bir işaretçi aradığınızı varsayıyorum. Eğer varsa, işaretleyicinin bilinen bir uzunlukta olduğunu varsayalım, örneğin tek bir bayt veya 3 baytlık bir dizi vs.

Yukarıdaki varsayımlar doğruysa, FileStream, Seek dosyasını dosyanın sonuna açabilirsiniz. eksi beklenen işaretçi uzunluğu baytları okuyorsa ve işaretleyici varsa ve tamamlandığında dosyayı işleyebileceğinizi biliyorsunuz.

sona Aradığınız -3 bayt dosyaları ayrıştırma yavaş parçası olduğunu biliyoruz aşağıdaki

// Seek -3 bytes starting from the end of the file 
fileStream.Seek(-3, SeekOrigin.End); 
+0

Arama yapmak, sıralı okunandan daha masraflı bir işlem olabilir ve birden fazla aramanın yapılması oldukça yavaş olabilir. – josephj1989

+0

Henüz denemediğim bir şey var, bu yüzden bir çekim yapmaya değer. Aramayı uygulamaya çalışacağım ve bu durumun hızlanıp yükselmediğini göreceğim. Hepinize teşekkürler. – monkeyninja

+3

@ josephj1989, 500 MB'lık bir dosya satırını satır sonuna ya da bellek dostu parçalara göre sonuna kadar okumanın, sonuna kadar doğrudan arama yapmaktan daha çabuk olduğunu mu söylüyorsunuz? Ve neden çoğul arar, benim belirttiğim varsayım, işaretçinin dosya sonunda olduğunu, böylece sadece tek bir arayış. –