17-bo‘lim

Fayllar va JSON

Fayl o'qish va yozish, yo'llar bilan ishlash, kataloglar, System.Text.Json bilan seriyalash va JSON ni obyektga aylantirish.

🕑 13 daqiqa o‘qish 📄 506 so‘z 👁 1 marta ko‘rilgan
Ushbu bo‘lim mundarijasi
  1. Fayl yozish va o'qish
  2. Qatorlar bilan ishlash
  3. Yo'llar bilan ishlash
  4. Kataloglar
  5. JSON - obyektni matnga aylantirish
  6. JSON ni obyektga aylantirish
  7. JSON ni faylga saqlash
  8. Foydali sozlamalar
  9. Xulosa

Dastur ishini saqlab qolishi kerak. Eng oddiy yo'l - faylga yozish. Ma'lumotni tuzilgan holda saqlash uchun esa JSON ishlatiladi.

Fayl yozish va o'qish #

CSHARP
string yol = Path.Combine(Path.GetTempPath(), "sinov.txt");

File.WriteAllText(yol, "Birinchi qator\nIkkinchi qator");

string matn = File.ReadAllText(yol);
Console.WriteLine($"O'qildi ({matn.Length} belgi):");
Console.WriteLine(matn);

File.Delete(yol);
Console.WriteLine($"Fayl mavjudmi: {File.Exists(yol)}");
Natija
O'qildi (29 belgi):
Birinchi qator
Ikkinchi qator
Fayl mavjudmi: False
MetodNima qiladi
File.WriteAllTextButun matnni yozadi (mavjudini o'chiradi)
File.AppendAllTextOxiriga qo'shadi
File.ReadAllTextButun faylni bitta satr qilib o'qiydi
File.ReadAllLinesQatorlar massivini qaytaradi
File.WriteAllLinesQatorlar massivini yozadi
File.ExistsFayl bormi
File.DeleteO'chiradi
WriteAllText mavjud faylni butunlay o'chiradi

Bu eng ko'p yo'qotishga sabab bo'ladigan metod. U ogohlantirmaydi, so'ramaydi - shunchaki eski mazmunni almashtiradi.

Qo'shish kerak bo'lsa AppendAllText ishlating.

Ehtiyot chorasi:

CSHARP
string yol = Path.Combine(Path.GetTempPath(), "muhim.txt");
File.WriteAllText(yol, "muhim ma'lumot");

if (File.Exists(yol))
{
    Console.WriteLine("Fayl bor - ustiga yozilmaydi");
}
else
{
    File.WriteAllText(yol, "yangi ma'lumot");
}

Console.WriteLine(File.ReadAllText(yol));
File.Delete(yol);
Natija
Fayl bor - ustiga yozilmaydi
muhim ma'lumot

Qatorlar bilan ishlash #

CSHARP
string yol = Path.Combine(Path.GetTempPath(), "shaharlar.txt");

File.WriteAllLines(yol, ["Namangan", "Andijon", "Samarqand"]);

string[] qatorlar = File.ReadAllLines(yol);
Console.WriteLine($"{qatorlar.Length} ta qator:");

for (int i = 0; i < qatorlar.Length; i++)
{
    Console.WriteLine($"  {i + 1}. {qatorlar[i]}");
}

File.AppendAllText(yol, "Toshkent\n");
Console.WriteLine($"Qo'shilgandan keyin: {File.ReadAllLines(yol).Length} ta");

File.Delete(yol);
Natija
3 ta qator:
  1. Namangan
  2. Andijon
  3. Samarqand
Qo'shilgandan keyin: 4 ta

Yo'llar bilan ishlash #

CSHARP
string yol = Path.Combine("hujjatlar", "hisobot", "2026-yil.txt");

Console.WriteLine($"To'liq yo'l:  {yol}");
Console.WriteLine($"Fayl nomi:    {Path.GetFileName(yol)}");
Console.WriteLine($"Kengaytmasiz: {Path.GetFileNameWithoutExtension(yol)}");
Console.WriteLine($"Kengaytma:    {Path.GetExtension(yol)}");
Console.WriteLine($"Papka:        {Path.GetDirectoryName(yol)}");
Console.WriteLine($"Almashtirish: {Path.ChangeExtension(yol, ".pdf")}");
Natija
To'liq yo'l:  hujjatlar/hisobot/2026-yil.txt
Fayl nomi:    2026-yil.txt
Kengaytmasiz: 2026-yil
Kengaytma:    .txt
Papka:        hujjatlar/hisobot
Almashtirish: hujjatlar/hisobot/2026-yil.pdf
Yo'lni qo'lda birlashtirmang
CSHARP
string yomon = "hujjatlar" + "\\" + "fayl.txt";     // faqat Windows'da
string yaxshi = Path.Combine("hujjatlar", "fayl.txt");

Windows teskari chiziq (\), Linux va macOS esa to'g'ri chiziq (/) ishlatadi. Path.Combine ishlayotgan tizimga mos ajratuvchini o'zi qo'yadi.

Yuqoridagi chiqishda / ko'rinishining sababi shu: misol Linux'da bajarildi. Windows'da xuddi shu kod \ bilan chiqaradi.

Bu Path.Combine ning aynan nima uchun kerakligini ko'rsatadi - bitta kod har ikkala tizimda to'g'ri ishlaydi.

Kataloglar #

CSHARP
string asos = Path.Combine(Path.GetTempPath(), "sinovkatalog");
string ichki = Path.Combine(asos, "ichki");

Directory.CreateDirectory(ichki);

File.WriteAllText(Path.Combine(asos, "a.txt"), "a");
File.WriteAllText(Path.Combine(asos, "b.txt"), "b");
File.WriteAllText(Path.Combine(ichki, "c.txt"), "c");

Console.WriteLine($"Faqat asosda:  {Directory.GetFiles(asos).Length} ta");
int hammasi = Directory
    .GetFiles(asos, "*", SearchOption.AllDirectories).Length;
Console.WriteLine($"Ichkisi bilan: {hammasi} ta");
Console.WriteLine(
    $"Papkalar:      {Directory.GetDirectories(asos).Length} ta");

Directory.Delete(asos, recursive: true);
Console.WriteLine($"Katalog mavjudmi: {Directory.Exists(asos)}");
Natija
Faqat asosda:  2 ta
Ichkisi bilan: 3 ta
Papkalar:      1 ta
Katalog mavjudmi: False

JSON - obyektni matnga aylantirish #

CSHARP
using System.Text.Json;

var talaba = new Talaba("Husanboy Qodirov", 25,
    ["Informatika", "Matematika"]);

string json = JsonSerializer.Serialize(talaba, new JsonSerializerOptions
{
    WriteIndented = true
});

Console.WriteLine(json);

record Talaba(string Ism, int Yosh, string[] Fanlar);
Natija
{
  "Ism": "Husanboy Qodirov",
  "Yosh": 25,
  "Fanlar": [
    "Informatika",
    "Matematika"
  ]
}

JSON ni obyektga aylantirish #

CSHARP
using System.Text.Json;

string json = """
    {
      "Ism": "Malika Tursunova",
      "Yosh": 20,
      "Fanlar": ["Fizika", "Kimyo"]
    }
    """;

Talaba? t = JsonSerializer.Deserialize<Talaba>(json);

if (t is not null)
{
    Console.WriteLine($"{t.Ism}, {t.Yosh} yosh");
    Console.WriteLine($"Fanlari: {string.Join(", ", t.Fanlar)}");
}

record Talaba(string Ism, int Yosh, string[] Fanlar);
Natija
Malika Tursunova, 20 yosh
Fanlari: Fizika, Kimyo
Nomlar mos kelishi kerak

Sukut bo'yicha System.Text.Json xossa nomlarini katta-kichik harfni hisobga olib solishtiradi.

Ya'ni JSON da "ism" bo'lsa-yu, sinfda Ism bo'lsa, qiymat o'rnatilmaydi va xato ham bermaydi - shunchaki null qoladi.

Yechim:

CSHARP
using System.Text.Json;

string json = """{ "ism": "Nodira", "yosh": 22 }""";

var sozlamalar = new JsonSerializerOptions
{
    PropertyNameCaseInsensitive = true
};

var a = JsonSerializer.Deserialize<Odam>(json);
var b = JsonSerializer.Deserialize<Odam>(json, sozlamalar);

Console.WriteLine($"Sozlamasiz: ism='{a?.Ism}', yosh={a?.Yosh}");
Console.WriteLine($"Sozlama bilan: ism='{b?.Ism}', yosh={b?.Yosh}");

class Odam
{
    public string? Ism { get; set; }
    public int Yosh { get; set; }
}
Natija
Sozlamasiz: ism='', yosh=0
Sozlama bilan: ism='Nodira', yosh=22

Birinchi holatda hech narsa o'rnatilmadi, lekin xato ham bo'lmadi - bu eng xavfli turdagi nosozlik.

JSON ni faylga saqlash #

CSHARP
using System.Text.Json;

string yol = Path.Combine(Path.GetTempPath(), "talabalar.json");

List<Talaba> royxat =
[
    new("Husanboy", 92),
    new("Malika", 78),
    new("Nodira", 85)
];

File.WriteAllText(yol, JsonSerializer.Serialize(royxat));

var oqilgan =
    JsonSerializer.Deserialize<List<Talaba>>(File.ReadAllText(yol)) ?? [];

Console.WriteLine($"Saqlandi va o'qildi: {oqilgan.Count} ta");
Console.WriteLine($"O'rtacha ball: {oqilgan.Average(t => t.Ball):F1}");
Console.WriteLine($"Eng yuqori: {oqilgan.MaxBy(t => t.Ball)?.Ism}");

File.Delete(yol);

record Talaba(string Ism, int Ball);
Natija
Saqlandi va o'qildi: 3 ta
O'rtacha ball: 85.0
Eng yuqori: Husanboy

Foydali sozlamalar #

CSHARP
using System.Text.Encodings.Web;
using System.Text.Json;
using System.Text.Json.Serialization;

var talaba = new Talaba("Husanboy", null);

Console.WriteLine("Sukut bo'yicha:");
Console.WriteLine(JsonSerializer.Serialize(talaba));

Console.WriteLine("\nO'zbek harflari va null siz:");
Console.WriteLine(JsonSerializer.Serialize(
    new Talaba("Farg'ona", null),
    new JsonSerializerOptions
    {
        Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
        DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull
    }));

record Talaba(string Ism, string? Izoh);
Natija
Sukut bo'yicha:
{"Ism":"Husanboy","Izoh":null}

O'zbek harflari va null siz:
{"Ism":"Farg'ona"}
Apostrof nega ' bo'lib qoldi?

System.Text.Json sukut bo'yicha xavfsizlikni ustun qo'yadi va HTML da xavfli bo'lishi mumkin bo'lgan belgilarni - apostrof, <, >, & - Unicode kodiga aylantiradi.

UnsafeRelaxedJsonEscaping faqat <, >, & kabi belgilarni qoldiradi, lekin apostrofni baribir qochiradi.

Bu muammo emas: JSON o'qiganda ' yana apostrofga aylanadi. Faqat faylni ko'z bilan o'qish biroz noqulay bo'ladi.

Fayl bilan ishlashda istisnoga tayyor turing

Fayl amallari ko'p sabab bilan muvaffaqiyatsiz bo'lishi mumkin: fayl yo'q, ruxsat yetarli emas, disk to'lgan, fayl boshqa dastur tomonidan band.

CSHARP
string yol = Path.Combine(Path.GetTempPath(), "yoq-fayl-12345.txt");

try
{
    Console.WriteLine(File.ReadAllText(yol));
}
catch (FileNotFoundException)
{
    Console.WriteLine("Fayl topilmadi");
}
catch (UnauthorizedAccessException)
{
    Console.WriteLine("Ruxsat yo'q");
}
catch (IOException x)
{
    Console.WriteLine($"Kirish-chiqish xatosi: {x.Message}");
}
Natija
Fayl topilmadi

Diqqat: IOException ni oxiriga qo'ying - FileNotFoundException undan meros oladi, shuning uchun yuqorida bo'lsa qolganlari hech qachon ishlamaydi.

Amaliy topshiriq
  1. Faylga matn yozing va qaytadan o'qing.
  2. AppendAllText bilan qo'shimcha qator qo'shing.
  3. WriteAllText mavjud faylni o'chirishini tekshiring.
  4. ReadAllLines bilan qatorlarni raqamlab chiqaring.
  5. Path.Combine va Path.GetExtension ni sinang.
  6. Katalog yaratib, ichida fayllar yarating va sanang.
  7. record ni JSON ga aylantiring.
  8. JSON dan obyektni qaytarib oling.
  9. JSON dagi kichik harfli nomlarni PropertyNameCaseInsensitive bilan o'qing.
  10. Mavjud bo'lmagan faylni o'qishga urinib, istisnoni ushlang.

Xulosa #

  • File.WriteAllText mavjud faylni butunlay almashtiradi - qo'shish uchun AppendAllText.
  • Yo'llarni Path.Combine bilan qo'shing - u tizimga mos ajratuvchini o'zi tanlaydi.
  • Directory.GetFiles ga SearchOption.AllDirectories bersangiz, ichki papkalarni ham qidiradi.
  • JsonSerializer.Serialize obyektni JSON ga, Deserialize<T> teskarisiga aylantiradi.
  • JSON nomlari katta-kichik harf bilan solishtiriladi; mos kelmasa jimgina null qoladi.
  • WriteIndented, PropertyNameCaseInsensitive va DefaultIgnoreCondition - eng ko'p kerak bo'ladigan sozlamalar.
  • Fayl amallarini try/catch bilan o'rang; IOException ni oxiriga qo'ying.

Keyingi bo'limda asinxron dasturlashni o'rganamiz.

Xatolik topdingizmi?

Imlo xatosi, ishlamaydigan kod yoki noto‘g‘ri ma‘lumotni ko‘rsangiz - bizga xabar bering. Har bir xabar administrator tomonidan ko‘rib chiqiladi.