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.
Ushbu bo‘lim mundarijasi
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 #
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)}");
O'qildi (29 belgi):
Birinchi qator
Ikkinchi qator
Fayl mavjudmi: False
| Metod | Nima qiladi |
|---|---|
File.WriteAllText | Butun matnni yozadi (mavjudini o'chiradi) |
File.AppendAllText | Oxiriga qo'shadi |
File.ReadAllText | Butun faylni bitta satr qilib o'qiydi |
File.ReadAllLines | Qatorlar massivini qaytaradi |
File.WriteAllLines | Qatorlar massivini yozadi |
File.Exists | Fayl bormi |
File.Delete | O'chiradi |
WriteAllText mavjud faylni butunlay o'chiradiBu 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:
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);
Fayl bor - ustiga yozilmaydi
muhim ma'lumot
Qatorlar bilan ishlash #
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);
3 ta qator:
1. Namangan
2. Andijon
3. Samarqand
Qo'shilgandan keyin: 4 ta
Yo'llar bilan ishlash #
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")}");
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
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 #
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)}");
Faqat asosda: 2 ta
Ichkisi bilan: 3 ta
Papkalar: 1 ta
Katalog mavjudmi: False
JSON - obyektni matnga aylantirish #
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);
{
"Ism": "Husanboy Qodirov",
"Yosh": 25,
"Fanlar": [
"Informatika",
"Matematika"
]
}
JSON ni obyektga aylantirish #
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);
Malika Tursunova, 20 yosh
Fanlari: Fizika, Kimyo
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:
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; }
}
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 #
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);
Saqlandi va o'qildi: 3 ta
O'rtacha ball: 85.0
Eng yuqori: Husanboy
Foydali sozlamalar #
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);
Sukut bo'yicha:
{"Ism":"Husanboy","Izoh":null}
O'zbek harflari va null siz:
{"Ism":"Farg'ona"}
' 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 amallari ko'p sabab bilan muvaffaqiyatsiz bo'lishi mumkin: fayl yo'q, ruxsat yetarli emas, disk to'lgan, fayl boshqa dastur tomonidan band.
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}");
}
Fayl topilmadi
Diqqat: IOException ni oxiriga qo'ying - FileNotFoundException
undan meros oladi, shuning uchun yuqorida bo'lsa qolganlari hech
qachon ishlamaydi.
- Faylga matn yozing va qaytadan o'qing.
AppendAllTextbilan qo'shimcha qator qo'shing.WriteAllTextmavjud faylni o'chirishini tekshiring.ReadAllLinesbilan qatorlarni raqamlab chiqaring.Path.CombinevaPath.GetExtensionni sinang.- Katalog yaratib, ichida fayllar yarating va sanang.
recordni JSON ga aylantiring.- JSON dan obyektni qaytarib oling.
- JSON dagi kichik harfli nomlarni
PropertyNameCaseInsensitivebilan o'qing. - Mavjud bo'lmagan faylni o'qishga urinib, istisnoni ushlang.
Xulosa #
File.WriteAllTextmavjud faylni butunlay almashtiradi - qo'shish uchunAppendAllText.- Yo'llarni
Path.Combinebilan qo'shing - u tizimga mos ajratuvchini o'zi tanlaydi. Directory.GetFilesgaSearchOption.AllDirectoriesbersangiz, ichki papkalarni ham qidiradi.JsonSerializer.Serializeobyektni JSON ga,Deserialize<T>teskarisiga aylantiradi.- JSON nomlari katta-kichik harf bilan solishtiriladi; mos
kelmasa jimgina
nullqoladi. WriteIndented,PropertyNameCaseInsensitivevaDefaultIgnoreCondition- eng ko'p kerak bo'ladigan sozlamalar.- Fayl amallarini
try/catchbilan o'rang;IOExceptionni oxiriga qo'ying.
Keyingi bo'limda asinxron dasturlashni o'rganamiz.
O‘qish tarixini saqlamoqchimisiz?
Tizimga kirsangiz, tugatgan bo‘limlaringiz saqlanadi va qoldirgan joyingizdan davom etasiz.
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.