C# Metin dosyasındaki bir değeri değiştirmek

Arkadaşlar Merhaba

Bir metin dosyam var bunun içinde kullanıcı adı ve bir sayıyı tutuyorum. Bu sayıyı ekranda chart verisinde kullanıyorum
Bir butona ne kadar tıkladıysa bu sayıyı veritabanına işiliyorum.Tekrar bu veriyi alıp görselleştiriyorum
Takıldığım nokta ise veritabanında birçok kullanıcı var.

Kullancı veritabanımda; ahmet#1 olarak tutuluyor ‘#’ ifadesini split ile daha sonra ayırıyorum
ben burada 1 değerini 2 yapmak istediğim zaman veritabanının hepsini siliyor ve bu değer 2,3,4 diye artırıyor
Fakat yapmak istediğim hiçbir kullanıcıyı silmeden bu değerin artırılması. Değeri artırabiliyorum bunda bir sorun yok ama veritabanını silerek artırıyor

Kodlarım şu şekilde;

 bool yaziciGirdimi = true;
            string veriCek = "", line = "";
            string[] split;
            int okunanFitnessSayisi = 0;
            StreamReader okuyucu = new StreamReader("Chart/OkunanFitnesSayısı.txt");
            while (!okuyucu.EndOfStream)
            {
                okunanFitnessSayisi += 1;
                veriCek = okuyucu.ReadLine();
                split = veriCek.Split('#');
                if (kulAdi == split[0])
                {
                    int cevir = Convert.ToInt32(Convert.ToInt32(split[1]) + okunanFitnessSayisi);
                    string sayiSil = split[1].Replace(split[1].ToString(), "");
                    okuyucu.Close(); 
                    StreamWriter yazici = new StreamWriter("Chart/OkunanFitnesSayısı.txt", false);
                    yazici.Write(kulAdi + "#" + cevir);
                    yaziciGirdimi = false;
                    yazici.Close();
                    break;
                }
               
            }
            if (yaziciGirdimi)
            {
                okuyucu.Close();
                StreamWriter yazici = new StreamWriter("Chart/OkunanFitnesSayısı.txt", true);
                yazici.WriteLine(Environment.NewLine + kulAdi + "#" + okunanFitnessSayisi);
                yazici.Close();
            }

Kodun yukarıdaki kısmını eksik yazmışsınız. Sadece okunanFitnessSayisi'nı değiştirdiğiniz kullanıcıyı yazıyorsunuz. Diğer kullanıcıların değerlerini de tekrardan eklemelisiniz.

while döngüsünün içine bir else ifadesi ekleyin ve veriCek değişkeninin değerini bir listede tutun. Daha sonra yazici.WriteLine kullanarak veritabanına ekleyin.

Kişisel bir gözlem olarak söylüyorum. Veritabanında bir değişiklik yapmak için aşırı kötü bir yöntem kullanıyorsunuz. Bu uygulamada 5 10 belki 100 tane veri üzerinde çalışıyorsunuz. Ancak veritabanları çok daha büyük işlem hacimleri için tasarlanan dosyalardır. Milyonlarca milyarlarca işlem olduğunda bu kullandığınız yöntem uygulamayı aşırı yavaşlatır.

Bu durumlarda arama algoritmaları veya benzeri optimizasyon yöntemleri kullanılıyor. Daha küçük bir uygulama tasarlayacaksanız daha önce söylediğim JSON yapısı kolaylık sağlıyor.

hocam söylediğiniz şeyi anlayamadım kısa bir kod yazarmısınız lütfen

hocam biliyorum bunu farklı bir nedenden dolayı yapıyorum. Normalde daha iyi sistemler var dediğiniz gibi

Kodu yazmaya başlayınca bu şekilde olduğunu fark ettim. Bir an için beynim yandı.

while (!okuyucu.EndOfStream)
{
    okunanFitnessSayisi += 1;
    veriCek = okuyucu.ReadLine();
}

Yazdığınız kodu bu kadar seviyeye daralttığımızda siz de göreceksiniz ki burada her okuma yaptığınızda okunanFitnessSayisi değişkeni 1 defa artırılıyor. Yani bu değişken okunan fitness sayısını değil okunan satır sayısını gösteriyor. Daha sonra siz bu değişkeni aşağıdaki satırda kullanıyorsunuz:

int cevir = Convert.ToInt32(Convert.ToInt32(split[1]) + okunanFitnessSayisi);

Buradaki okunanFitnessSayisi yerine 1 yazıp bu değişkeni kodunuzdan tamamen kaldırabilirsiniz.

Açıkçası bir şeyler denedim. Birkaç kaynaktan bakarak yazdım. Bilgisayarımda c# çalıştıracak bir program olmadığı için çalıştıramadım. Anlamadığınız yerde yine yardımcı olmaya çalışırım.

// Değişmeyen kullanıcılar için bir liste oluşturalım
List<string> degismeyenKullanicilar = new List<string>();
bool yaziciGirdimi = true;
string veriCek = "", line = "";
string[] split;
int okunanFitnessSayisi = 0;
StreamReader okuyucu = new StreamReader("Chart/OkunanFitnesSayısı.txt");
while (!okuyucu.EndOfStream)
{
    okunanFitnessSayisi += 1;
    veriCek = okuyucu.ReadLine();
    split = veriCek.Split('#');
    if (kulAdi == split[0])
    {
        int cevir = Convert.ToInt32(Convert.ToInt32(split[1]) + okunanFitnessSayisi);
        string sayiSil = split[1].Replace(split[1].ToString(), "");
        okuyucu.Close(); 
        StreamWriter yazici = new StreamWriter("Chart/OkunanFitnesSayısı.txt", false);
        yazici.Write(kulAdi + "#" + cevir);
        yaziciGirdimi = false;
        yazici.Close();
        break;
    }
    // Herhangi bir değişiklik yapmadığımız kullanıcıları ve okunanFitnessSayisi değerlerini
    // listemize ekleyelim.
    else
    {
        degismeyenKullanicilar.Add(veriCek)
    }
    
}
if (yaziciGirdimi)
{
    okuyucu.Close();
    StreamWriter yazici = new StreamWriter("Chart/OkunanFitnesSayısı.txt", true);
    yazici.WriteLine(Environment.NewLine + kulAdi + "#" + okunanFitnessSayisi);
    yazici.Close();
}
// Veritabanına eklenmeyen değişkenleri ekleyelim.
StreamWriter yazici = new StreamWriter("Chart/OkunanFitnesSayısı.txt", true);
foreach(string eklenmeyen in degismeyenKullanicilar.ToArray())
{
    yazici.WriteLine(eklenmeyen)
}
yazici.Close()

Umarım yardımcı olabilmişimdir.
Kaynaklar:

elinize sağlık hocam işim çözüldü var olasın

1 Beğeni

hocam tekrardan merhaba

Yazdığınız kod çalışıyor fakat sorunlu bir nokta var

Eğer butona 10,20 defa aynı anda tıklanınca surekli

  if (kulAdi == split[0])
    {
        int cevir = Convert.ToInt32(Convert.ToInt32(split[1]) + okunanFitnessSayisi);
        string sayiSil = split[1].Replace(split[1].ToString(), "");
        okuyucu.Close(); 
        StreamWriter yazici = new StreamWriter("Chart/OkunanFitnesSayısı.txt", false);
        yazici.Write(kulAdi + "#" + cevir);
        yaziciGirdimi = false;
        yazici.Close();
        break;
    }

bu koda giriyor ve bütün verileri siliyor

if (yaziciGirdimi)
{
    okuyucu.Close();
    StreamWriter yazici = new StreamWriter("Chart/OkunanFitnesSayısı.txt", true);
    yazici.WriteLine(Environment.NewLine + kulAdi + "#" + okunanFitnessSayisi);
    yazici.Close();
}
// Veritabanına eklenmeyen değişkenleri ekleyelim.
StreamWriter yazici = new StreamWriter("Chart/OkunanFitnesSayısı.txt", true);
foreach(string eklenmeyen in degismeyenKullanicilar.ToArray())
{
    yazici.WriteLine(eklenmeyen)
}
yazici.Close()

buraya daha sonra hiç girmiyor

hocam tekrardan merhaba

hocam yazdığınız kod çalıştı fakat bir yerde sorun var.

mesela kullanıcı 10,20 defa butona bastığı zaman su koda hiç girmiyor

if (yaziciGirdimi)
{
    okuyucu.Close();
    StreamWriter yazici = new StreamWriter("Chart/OkunanFitnesSayısı.txt", true);
    yazici.WriteLine(Environment.NewLine + kulAdi + "#" + 1);
    yazici.Close();
}
// Veritabanına eklenmeyen değişkenleri ekleyelim.
StreamWriter yazici = new StreamWriter("Chart/OkunanFitnesSayısı.txt", true);
foreach(string eklenmeyen in degismeyenKullanicilar.ToArray())
{
    yazici.WriteLine(eklenmeyen)
}
yazici.Close()

Süreki şu koda girdiği için de veritabanını siliyor yeni kullanıcıyı ekliyor.

 if (kulAdi == split[0])
                {
                    int cevir = Convert.ToInt32(Convert.ToInt32(split[1]) + 1);
                    //string sayiSil = split[1].Replace(split[1].ToString(), "");
                    okuyucu.Close(); 
                    StreamWriter yazici = new StreamWriter("Chart/OkunanFitnesSayısı.txt", false);
                    yazici.Write(kulAdi + "#" + cevir);
                    yaziciGirdimi = false;
                    yazici.Close();
                    break;
                }
                // Herhangi bir değişiklik yapmadığımız kullanıcıları ve okunanFitnessSayisi değerlerini
                // listemize ekleyelim.
                else
                {
                    degismeyenKullanicilar.Add(veriCek);
                }

üstad bir şey daha

şimdi butona ilk tıklıyorum sizin yazdığınız kod çalışıyor bir sorun yok.
Fakat ikinci tıklamada veritabanından verileri çekiyor hangi kullanıcı adıysa sadece onu ekliyor diğerlerini siliyor

bende şöyle yapsam olur mu?
Girilen kullanıcı isminin dışında başka kullanıcı isimlerini başka bir text dosyasına kaydedip öyle mi halledeyim?

Konu şu.

Dosyanın, metin, ini, xml, sql ne olduğu hiç önemli değil.

Eksik bilginiz, veri yapıları ve dosya kayıtları konusu.

Bir dosyaya kayıtlar yazdığınızda ve bunu temel c# kodları ile yapıyorsanız, ard arda eklersin, siler yerine yazarsınız vs.

Ama veri tabanı gibi araya kayıt eklemek, kayıt düzeltmek, kayıt çıkarmak gibi farklı işlemler için kendiniz kodlar yazabilmelisiniz.

Bir dosya sadece sıraldığınız şekilde yazılı veri topluluğudur. Bunları birimlere bölerek, her birime bir erişim şekli tanımlayarak, yani oluşturduğunuz veri seti yada kaydının şeklini tanımlayarak bunları belli bir ilişki içerisinde bir birine bağlamalısınız.

Sonrasında bunlar üzerinde arama işlemlerini aradan kayıt ekleyip çıkarmayı öğrenmelisiniz.

Bunun mantığını oluşturmadan sihirli kodlar işim görüldü şeklinde bu iş ilerlemez.

Siz benzer bir konuda, ini dosyası kullanmak, sql veri tabanı kullanmak xml yapısı json kullanmak dahil bir çok yol önerdim.

Şimdi en basitiden bir dosyaya neden araya kayıt ekleyemiyorsunuz anlatayım.

Kayıt araya eklenmez.

Araya eklenecek kayda kadar başka bir dosyaya yazılır, sonrasına eklenecek kayıt eklenir, daha sonra da ilk kalan dosyanın devamı yeni dosyanın ardına eklenir.

İlk dosya silinir, ikinci araya kayıt eklenmiş dosya birinciyle aynı isimde yeniden kaydedilir.

Yani txt dosyaları veri tabanı gibi kolayca bir komutla veri eklenip çıkarılan dosyalar değildir. Yani içeriği kısmen okunur, sonrasında temp bir dosyada birleştirilip eskisi ile değiştirilir.

Ve bunu hazır bir komutla yapamazsınız. Sizin kodlamanız gerekir.

Bu şekilde progamın bir orası bir burası bir şurası sorularak program yazmak size hiç bir şey kazandırmaz.

Kod faciaya dönüşüyor.

Lütfen, veri yapıları, dosya yapıları, kayıtlar kayıtlarda arama, veritabanı oluşturma gibi konulara bakın.

Bu şekilde alacağınz yardım sadece size balık vermek oluyor ve size çok balık lazım gibi görünüyor.

Ha bunun dışında, gerçek veri tabanları bu işi bu şekilde yapamaz sıra yoktur ilişki indeksi tutar ve o indeks değerlerini değiştirerek ilgili kayıtları günceller. Ama madem txt basitçe tarif ettiğim şekilde hareket edip kodunuzu düzeltebilirsiniz.

Merhaba

Yukarıda söylediğim gibi bu kodun verimliliği bu kadar. Her seferinde bir dosyayı baştan sona okuyup burada tek bir karakteri değiştirdikten sonra bütün dosyayı tekrar kaydediyorsunuz. Değiştirmek istediğiniz o tek karakteri daha hızlı bulmalısınız. Sizden önce milyonlarca insan bu problemle karşılaştı. Bilgisayar bilimi bu sorun karşısında key-value yöntemini bir standart haline getirdi. Dictionary diye adlandırdığımız bir veri tipini ve Json olarak adlandırdığımız bir dosya tipini bütün programlama dillerinde bulabilirsiniz.

Dictionary tipinde bir değişken oluşturup onu bir txt dosyasına kaydedebilirsiniz ya da direkt olarak json kullanırsınız. Tercih sizin. Ancak bu kodları tamamen silmelisiniz.

Programcılar buna “yanlış yazmışım, şimdi yeniden yazıyorum.” demek yerine “refactoring” diyorlar.

Belkide olaya daha basit yaklaşmak gerekiyor. Normalde önermem. Çünkü çok büyük dosyalarda dosyanın tamamını belleğe almak ve aramak mümkün olmayabilir.

Ama diğer taraftan zaten kaç kullanıcı tutuyor olabilirsiniz ki.

Windows filemapping konusuna da girmeyeceğim.

c# - How to find and replace text in a file - Stack Overflow

string text = File.ReadAllText("test.txt");
text = text.Replace("some text", "new value");
File.WriteAllText("test.txt", text);

Yapmanız gereken tek şey, kullanıcı adı ve değer satırını bulmak ve ve replace yordamı ile yeniden kullanıcı adını ve gireceğiniz rakamı eklemek.