Ver3.5 ๐๏ธ C# ๋ฐ์ดํฐ ์ฒ๋ฆฌ์ ํ์ฑ ์์ ์ ๋ณต โ JSON ยท XML ยท CSV ๋ณํ ๊ธฐ๋ฒ ์ค์ ๊ฐ์ด๋

๐๏ธ C# ๋ฐ์ดํฐ ์ฒ๋ฆฌ์ ํ์ฑ ์์ ์ ๋ณต โ JSON ยท XML ยท CSV ๋ณํ ๊ธฐ๋ฒ ์ค์ ๊ฐ์ด๋
๋ฐ์ดํฐ๋ฅผ ์์ ์์ฌ๋ก ์ฃผ๋ฌด๋ฅด๋ C# ๊ฐ๋ฐ์๊ฐ ๋๊ณ ์ถ๋ค๋ฉด? ์ง๊ธ ๋ฐ๋ก ์์ํด๋ณด์! ๐
JSON, XML, CSV โ ์ธ ๊ฐ์ง ํฌ๋งท์ ํ์ฑ๊ณผ ๋ณํ์ ํ ๋ฒ์ ๋ง์คํฐํ๋ ์ค์ ์ฌ์ ๐
๐ค ๋ฐ์ดํฐ ํ์ฑ, ์ ์ด๋ ๊ฒ ์ค์ํ ๊ฑฐ์ผ?
์์งํ ๋งํ๋ฉด, ์์ฆ ๊ฐ๋ฐํ๋ฉด์ ๋ฐ์ดํฐ ํ์ฑ์ ์ ์ฐ๋ ํ๋ก์ ํธ๋ ๊ฑฐ์ ์๋ค๊ณ ๋ด๋ ๋ฌด๋ฐฉํด.
API ํธ์ถํ๋ฉด JSON์ด ๋ ์์ค๊ณ , ๋ ๊ฑฐ์ ์์คํ
์ XML์ ๋ฑ์ด๋ด๊ณ , ์์
๋ฐ์ดํฐ๋ CSV๋ก ๋์ด์ค๊ณ โฆ
์ด ์ธ ๊ฐ์ง ํฌ๋งท๋ง ์ ๋๋ก ๋ค๋ฃฐ ์ค ์์๋ ๊ฐ๋ฐ ์์ฐ์ฑ์ด ๋์ ๋๊ฒ ๋ฌ๋ผ์ง๋ค๋ ๊ฑฐ, ๊ฒฝํํด๋ณธ ์ฌ๋์ ๋ค ์์ง! ๐
ํน์ ํ์์ผ๋ก ์ธ์ฝ๋ฉ๋ ๋ฌธ์์ด์ด๋ ๋ฐ์ดํธ ์คํธ๋ฆผ์ ๋ถ์ํด์, ํ๋ก๊ทธ๋จ์ด ์ฌ์ฉํ ์ ์๋ ๊ตฌ์กฐํ๋ ๋ฐ์ดํฐ๋ก ๋ณํํ๋ ๊ณผ์ ์ด์ผ.
์ฝ๊ฒ ๋งํ๋ฉด "์ธ๊ตญ์ด ํ ์คํธ๋ฅผ ์ฐ๋ฆฌ๋ง๋ก ๋ฒ์ญํ๋ ๊ฒ"๊ณผ ๋น์ทํ ๊ฐ๋ ์ด์ง!
C#์ .NET ์ํ๊ณ ๋๋ถ์ JSON, XML, CSV ํ์ฑ์ ์ํ ๊ฐ๋ ฅํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ค์ด ์ด๋ฏธ ์ ๊ฐ์ถฐ์ ธ ์์ด.
System.Text.Json, Newtonsoft.Json, System.Xml, LINQ to XML, CsvHelper ๊ฐ์ ๋๊ตฌ๋ค์ด ๋ํ์ ์ด์ผ.
์ด ๊ธ์์๋ ๊ฐ ํฌ๋งท๋ณ๋ก ํต์ฌ ๊ธฐ๋ฒ์ ์ค์ ์ฝ๋์ ํจ๊ป ํํค์ณ๋ณผ ๊ฑฐ์ผ. ์ค๋น๋์ง? ๐ฅ
| ํฌ๋งท | ์ฃผ์ ์ฌ์ฉ์ฒ | C# ์ฃผ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ | ํน์ง |
|---|---|---|---|
| JSON | REST API, ์ค์ ํ์ผ, NoSQL | System.Text.Json, Newtonsoft.Json | ๊ฐ๋ณ๊ณ ์ฝ๊ธฐ ์ฌ์ |
| XML | SOAP, ์ค์ ํ์ผ, ๋ฌธ์ ๊ตํ | System.Xml, XDocument, LINQ to XML | ์คํค๋ง ๊ฒ์ฆ ๊ฐ๋ฅ, ๋ค์์คํ์ด์ค ์ง์ |
| CSV | ์์ ๋ฐ์ดํฐ, ๋์ฉ๋ ๋ฐฐ์น, ๋ก๊ทธ | StreamReader, CsvHelper, TextFieldParser | ๋จ์ํ๊ณ ํธํ์ฑ ์ต๊ณ |
๐ฆ JSON ํ์ฑ โ C#์ ๋ ๊ฐ์ง ๊ฐ์
JSON์ ํ๋ ์น ๊ฐ๋ฐ์ ๊ตญ๋ฏผ ํฌ๋งท์ด๋ผ๊ณ ํด๋ ๊ณผ์ธ์ด ์๋์ผ.
C#์์ JSON์ ๋ค๋ฃจ๋ ๋ฐฉ๋ฒ์ ํฌ๊ฒ ๋ ๊ฐ์ง ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ก ๋๋์ด:
๐น System.Text.Json โ ๊ธฐ๋ณธ ๋ด์ฅ์ ํ
.NET 5 ์ด์์ด๋ผ๋ฉด ๋ณ๋ ์ค์น ์์ด ๋ฐ๋ก ์ธ ์ ์์ด.
์ฑ๋ฅ์ด ๋ฐ์ด๋๊ณ ๋ฉ๋ชจ๋ฆฌ ํจ์จ๋ ์ข์์ ๊ณ ์ฑ๋ฅ ์๋ฒ ์ ํ๋ฆฌ์ผ์ด์
์ ๋ฑ์ด์ผ!
๐ ๊ธฐ๋ณธ ์ญ์ง๋ ฌํ (JSON โ C# ๊ฐ์ฒด)
using System.Text.Json;
// ๋ชจ๋ธ ํด๋์ค ์ ์
public class User
{
public int Id { get; set; }
public string Name { get; set; }
public string Email { get; set; }
public bool IsActive { get; set; }
}
// JSON ๋ฌธ์์ด โ C# ๊ฐ์ฒด
string jsonString = @"{
""id"": 1,
""name"": ""ํ๊ธธ๋"",
""email"": ""hong@example.com"",
""isActive"": true
}";
User user = JsonSerializer.Deserialize<User>(jsonString);
Console.WriteLine($"์ด๋ฆ: {user.Name}, ์ด๋ฉ์ผ: {user.Email}");
// ์ถ๋ ฅ: ์ด๋ฆ: ํ๊ธธ๋, ์ด๋ฉ์ผ: hong@example.com
๐ ์ง๋ ฌํ (C# ๊ฐ์ฒด โ JSON)
// C# ๊ฐ์ฒด โ JSON ๋ฌธ์์ด
var newUser = new User
{
Id = 2,
Name = "๊น์ฒ ์",
Email = "kim@example.com",
IsActive = false
};
// ๊ธฐ๋ณธ ์ง๋ ฌํ
string json = JsonSerializer.Serialize(newUser);
// ์์๊ฒ ๋ค์ฌ์ฐ๊ธฐ ํฌํจ
var options = new JsonSerializerOptions
{
WriteIndented = true,
PropertyNamingPolicy = JsonNamingPolicy.CamelCase // ์นด๋ฉ์ผ์ด์ค๋ก ๋ณํ
};
string prettyJson = JsonSerializer.Serialize(newUser, options);
Console.WriteLine(prettyJson);
๐ ๋ฆฌ์คํธ(๋ฐฐ์ด) JSON ์ฒ๋ฆฌ
string jsonArray = @"[
{""id"": 1, ""name"": ""ํ๊ธธ๋""},
{""id"": 2, ""name"": ""๊น์ฒ ์""},
{""id"": 3, ""name"": ""์ด์ํฌ""}
]";
List<User> users = JsonSerializer.Deserialize<List<User>>(jsonArray);
foreach (var u in users)
{
Console.WriteLine($"ID: {u.Id}, ์ด๋ฆ: {u.Name}");
}
๐ JsonDocument๋ก ๋์ ํ์ฑ (๊ตฌ์กฐ๋ฅผ ๋ชจ๋ฅผ ๋)
string dynamicJson = @"{
""product"": ""๋
ธํธ๋ถ"",
""price"": 1500000,
""specs"": {
""cpu"": ""Intel i7"",
""ram"": ""16GB""
}
}";
using JsonDocument doc = JsonDocument.Parse(dynamicJson);
JsonElement root = doc.RootElement;
string product = root.GetProperty("product").GetString();
int price = root.GetProperty("price").GetInt32();
string cpu = root.GetProperty("specs").GetProperty("cpu").GetString();
Console.WriteLine($"์ ํ: {product}, ๊ฐ๊ฒฉ: {price:N0}์, CPU: {cpu}");
using ๋ธ๋ก ์์์ ์ฌ์ฉํด์ผ ํด. ๋ด๋ถ์ ์ผ๋ก ArrayPool์ ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์ Dispose()๋ฅผ ๊ผญ ํธ์ถํด์ค์ผ ๋ฉ๋ชจ๋ฆฌ ๋์๊ฐ ์์ด!
๐น Newtonsoft.Json โ ์ ์ฐํจ์ ๋ํ์
NuGet์์ Newtonsoft.Json ํจํค์ง๋ฅผ ์ค์นํ๋ฉด ๋ผ.
๋ ๋ณต์กํ ์๋๋ฆฌ์ค, ์ปค์คํ
์ปจ๋ฒํฐ, ๋์ ํ์
์ฒ๋ฆฌ์์ ์ฌ์ ํ ๊ฐ๋ ฅํ ์ ํ์ง์ผ!
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
// ๊ธฐ๋ณธ ์ญ์ง๋ ฌํ
string json = @"{""name"": ""ํ๊ธธ๋"", ""age"": 30}";
User user = JsonConvert.DeserializeObject<User>(json);
// ๊ธฐ๋ณธ ์ง๋ ฌํ
string result = JsonConvert.SerializeObject(user, Formatting.Indented);
// JObject๋ก ๋์ ํ์ฑ (๊ตฌ์กฐ ๋ชจ๋ฅผ ๋ ์ต๊ฐ!)
JObject jObj = JObject.Parse(json);
string name = (string)jObj["name"];
int age = (int)jObj["age"];
// JArray๋ก ๋ฐฐ์ด ์ฒ๋ฆฌ
string jsonArr = @"[{""id"":1},{""id"":2}]";
JArray jArr = JArray.Parse(jsonArr);
foreach (JObject item in jArr)
{
Console.WriteLine(item["id"]);
}
// ํน์ ์์ฑ์ JsonProperty ์ดํธ๋ฆฌ๋ทฐํธ ์ ์ฉ
public class Product
{
[JsonProperty("product_name")] // JSON ํค ์ด๋ฆ ๋งคํ
public string ProductName { get; set; }
[JsonIgnore] // ์ง๋ ฌํ์์ ์ ์ธ
public string InternalCode { get; set; }
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public string? Description { get; set; }
}
Newtonsoft.Json ์ถ์ฒ: ๋ณต์กํ ์ปค์คํ ๋ณํ, ๋ ๊ฑฐ์ ์ฝ๋ ํธํ, ๋์ JSON ์กฐ์์ด ๋ง์ ๋
๐ ์ปค์คํ JsonConverter ๋ง๋ค๊ธฐ (System.Text.Json)
// DateTime์ ํน์ ํฌ๋งท์ผ๋ก ์ง๋ ฌํํ๋ ์ปค์คํ
์ปจ๋ฒํฐ
public class KoreanDateConverter : JsonConverter<DateTime>
{
public override DateTime Read(ref Utf8JsonReader reader,
Type typeToConvert, JsonSerializerOptions options)
{
return DateTime.Parse(reader.GetString()!);
}
public override void Write(Utf8JsonWriter writer,
DateTime value, JsonSerializerOptions options)
{
writer.WriteStringValue(value.ToString("yyyy๋
MM์ dd์ผ"));
}
}
// ์ฌ์ฉ ์์
var options = new JsonSerializerOptions();
options.Converters.Add(new KoreanDateConverter());
var data = new { Name = "์ด๋ฒคํธ", Date = DateTime.Now };
string json = JsonSerializer.Serialize(data, options);
// ์ถ๋ ฅ: {"Name":"์ด๋ฒคํธ","Date":"2024๋
01์ 15์ผ"}
๐ท๏ธ XML ํ์ฑ โ ๋ ๊ฑฐ์์ ์, ์ฌ์ ํ ํ์ญ!
XML์ "๊ตฌ์์ด๋ค"๋ ํธ๊ฒฌ์ด ์์ง๋ง, ์ค์ ํ์
์์๋ ์ฌ์ ํ ์์ฒญ๋๊ฒ ๋ง์ด ์ฐ์ฌ.
SOAP ์น์๋น์ค, ์ค์ ํ์ผ(App.config, Web.config), ์คํผ์ค ๋ฌธ์(docx, xlsx ๋ด๋ถ), RSS ํผ๋ ๋ฑโฆ
C#์์ XML์ ๋ค๋ฃจ๋ ๋ฐฉ๋ฒ๋ ์ฌ๋ฌ ๊ฐ์ง๊ฐ ์๋๋ฐ, ์ํฉ์ ๋ง๊ฒ ๊ณจ๋ผ ์ฐ๋ ๊ฒ ํฌ์ธํธ์ผ! ๐ฏ
| ๋ฐฉ๋ฒ | ํน์ง | ์ถ์ฒ ์ํฉ |
|---|---|---|
| XmlDocument | DOM ๋ฐฉ์, ์ ํต์ , ์ง๊ด์ | ์~์ค๊ฐ ํฌ๊ธฐ XML, ์์ ์์ |
| XDocument (LINQ to XML) | LINQ ์ฟผ๋ฆฌ ๊ฐ๋ฅ, ํ๋์ | ๋ณต์กํ ์ฟผ๋ฆฌ, ์ ํ๋ก์ ํธ |
| XmlReader | ์คํธ๋ฆฌ๋ฐ ๋ฐฉ์, ๋ฉ๋ชจ๋ฆฌ ํจ์จ | ๋์ฉ๋ XML ์ฒ๋ฆฌ |
| XmlSerializer | ๊ฐ์ฒด ์ง๋ ฌํ/์ญ์ง๋ ฌํ | XML โ C# ๊ฐ์ฒด ๋ณํ |
๐น XDocument (LINQ to XML) โ ๊ฐ์ฅ ํ๋์ ์ธ ๋ฐฉ๋ฒ
LINQ to XML์ C# 3.0๋ถํฐ ๋์ ๋ ๋ฐฉ์์ผ๋ก, LINQ ์ฟผ๋ฆฌ๋ฅผ XML์ ๊ทธ๋๋ก ์ ์ฉํ ์ ์์ด์ ์ ๋ง ํธ๋ฆฌํด!
using System.Xml.Linq;
// XML ๋ฌธ์์ด ํ์ฑ
string xmlString = @"
<์ง์๋ชฉ๋ก>
<์ง์ ๋ถ์=""๊ฐ๋ฐํ"">
<์ด๋ฆ>ํ๊ธธ๋</์ด๋ฆ>
<๋์ด>30</๋์ด>
<๊ธ์ฌ>5000000</๊ธ์ฌ>
</์ง์>
<์ง์ ๋ถ์=""๋์์ธํ"">
<์ด๋ฆ>๊น์ฒ ์</์ด๋ฆ>
<๋์ด>28</๋์ด>
<๊ธ์ฌ>4500000</๊ธ์ฌ>
</์ง์>
<์ง์ ๋ถ์=""๊ฐ๋ฐํ"">
<์ด๋ฆ>์ด์ํฌ</์ด๋ฆ>
<๋์ด>32</๋์ด>
<๊ธ์ฌ>5500000</๊ธ์ฌ>
</์ง์>
</์ง์๋ชฉ๋ก>";
XDocument xDoc = XDocument.Parse(xmlString);
// LINQ๋ก ๊ฐ๋ฐํ ์ง์๋ง ํํฐ๋ง
var ๊ฐ๋ฐํ์ง์ = xDoc.Root
.Elements("์ง์")
.Where(e => (string)e.Attribute("๋ถ์") == "๊ฐ๋ฐํ")
.Select(e => new
{
์ด๋ฆ = (string)e.Element("์ด๋ฆ"),
๋์ด = (int)e.Element("๋์ด"),
๊ธ์ฌ = (int)e.Element("๊ธ์ฌ")
})
.OrderByDescending(e => e.๊ธ์ฌ);
foreach (var ์ง์ in ๊ฐ๋ฐํ์ง์)
{
Console.WriteLine($"{์ง์.์ด๋ฆ} ({์ง์.๋์ด}์ธ) - ๊ธ์ฌ: {์ง์.๊ธ์ฌ:N0}์");
}
๐ XDocument๋ก XML ์์ฑํ๊ธฐ
// C# ์ฝ๋๋ก XML ์ง์ ์์ฑ
XDocument newXml = new XDocument(
new XDeclaration("1.0", "utf-8", "yes"),
new XElement("์ ํ๋ชฉ๋ก",
new XElement("์ ํ",
new XAttribute("id", "001"),
new XElement("์ด๋ฆ", "๋
ธํธ๋ถ"),
new XElement("๊ฐ๊ฒฉ", 1500000),
new XElement("์ฌ๊ณ ", 50)
),
new XElement("์ ํ",
new XAttribute("id", "002"),
new XElement("์ด๋ฆ", "๋ง์ฐ์ค"),
new XElement("๊ฐ๊ฒฉ", 35000),
new XElement("์ฌ๊ณ ", 200)
)
)
);
// ํ์ผ๋ก ์ ์ฅ
newXml.Save("products.xml");
// ๋ฌธ์์ด๋ก ๋ณํ
string xmlOutput = newXml.ToString();
Console.WriteLine(xmlOutput);
๐น XmlSerializer โ ๊ฐ์ฒด์ XML์ ์๋์ผ๋ก ๋งคํ
using System.Xml.Serialization;
using System.IO;
// ์ง๋ ฌํํ ํด๋์ค ์ ์
[XmlRoot("์ง์")]
public class Employee
{
[XmlAttribute("๋ถ์")]
public string Department { get; set; }
[XmlElement("์ด๋ฆ")]
public string Name { get; set; }
[XmlElement("๋์ด")]
public int Age { get; set; }
[XmlIgnore] // XML์์ ์ ์ธ
public string InternalId { get; set; }
}
[XmlRoot("์ง์๋ชฉ๋ก")]
public class EmployeeList
{
[XmlElement("์ง์")]
public List<Employee> Employees { get; set; } = new();
}
// ์ง๋ ฌํ (C# ๊ฐ์ฒด โ XML)
var empList = new EmployeeList
{
Employees = new List<Employee>
{
new Employee { Department = "๊ฐ๋ฐํ", Name = "ํ๊ธธ๋", Age = 30 },
new Employee { Department = "๋์์ธํ", Name = "๊น์ฒ ์", Age = 28 }
}
};
var serializer = new XmlSerializer(typeof(EmployeeList));
using var writer = new StringWriter();
serializer.Serialize(writer, empList);
string xmlResult = writer.ToString();
// ์ญ์ง๋ ฌํ (XML โ C# ๊ฐ์ฒด)
using var reader = new StringReader(xmlResult);
var deserialized = (EmployeeList)serializer.Deserialize(reader);
Console.WriteLine($"์ง์ ์: {deserialized.Employees.Count}");
๐น XmlReader โ ๋์ฉ๋ XML์ ๊ตฌ์์
์๋ฐฑ MB์ง๋ฆฌ XML ํ์ผ์ ์ฒ๋ฆฌํด์ผ ํ๋ค๋ฉด? XmlDocument๋ XDocument๋ ์ ์ฒด๋ฅผ ๋ฉ๋ชจ๋ฆฌ์ ์ฌ๋ฆฌ๊ธฐ ๋๋ฌธ์ ์ํํด.
XmlReader๋ ์คํธ๋ฆฌ๋ฐ ๋ฐฉ์์ผ๋ก ํ ์ค์ฉ ์ฝ์ด์ ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋์ ์ต์ํํด!
using System.Xml;
// ์คํธ๋ฆฌ๋ฐ ๋ฐฉ์์ผ๋ก ๋์ฉ๋ XML ์ฝ๊ธฐ
using XmlReader reader = XmlReader.Create("large_data.xml");
while (reader.Read())
{
// ์์ ํ๊ทธ์ผ ๋
if (reader.NodeType == XmlNodeType.Element && reader.Name == "์ง์")
{
string ๋ถ์ = reader.GetAttribute("๋ถ์");
// ํ์ ์์ ์ฝ๊ธฐ
using XmlReader subtree = reader.ReadSubtree();
while (subtree.Read())
{
if (subtree.NodeType == XmlNodeType.Element)
{
switch (subtree.Name)
{
case "์ด๋ฆ":
Console.Write($"์ด๋ฆ: {subtree.ReadElementContentAsString()}, ");
break;
case "๊ธ์ฌ":
Console.WriteLine($"๊ธ์ฌ: {subtree.ReadElementContentAsInt():N0}์");
break;
}
}
}
}
}
XNamespace ns = "http://example.com/schema";xDoc.Root.Elements(ns + "์ง์") ์ด๋ฐ ์์ผ๋ก ๋ค์์คํ์ด์ค๋ฅผ ๋ช
์ํด์ค์ผ ํด!
๐ CSV ํ์ฑ โ ๋จ์ํ์ง๋ง ํจ์ ์ด ๋ง์!
CSV๋ ๊ฒ๋ณด๊ธฐ์ ๋จ์ํด ๋ณด์ด์ง๋ง, ์ค์ ๋ก ํ์ฑํ๋ค ๋ณด๋ฉด ์๊ฐ์ง๋ ๋ชปํ ํจ์ ๋ค์ด ๋ง์.
์ผํ๊ฐ ํฌํจ๋ ๋ฐ์ดํฐ, ์ค๋ฐ๊ฟ์ด ํฌํจ๋ ํ๋, ์ธ์ฝ๋ฉ ๋ฌธ์ , ๋ฐ์ดํ ์ฒ๋ฆฌโฆ
์ด๋ฐ ๊ฒ๋ค์ ์ ๋๋ก ์ฒ๋ฆฌํ๋ ค๋ฉด ์ง์ ๊ตฌํ๋ณด๋ค๋ CsvHelper ๊ฐ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฐ๋ ๊ฒ ํจ์ฌ ์์ ํด! ๐
๐น ๊ธฐ๋ณธ StreamReader๋ก CSV ์ฝ๊ธฐ
๊ฐ๋จํ CSV๋ผ๋ฉด StreamReader๋ก๋ ์ถฉ๋ถํด. ํ์ง๋ง ๋ณต์กํ ์ผ์ด์ค๋ ์ฃผ์๊ฐ ํ์ํด!
using System.IO;
// ๊ธฐ๋ณธ CSV ์ฝ๊ธฐ
string csvContent = @"์ด๋ฆ,๋์ด,์ด๋ฉ์ผ,๋์
ํ๊ธธ๋,30,hong@example.com,์์ธ
๊น์ฒ ์,28,kim@example.com,๋ถ์ฐ
์ด์ํฌ,32,lee@example.com,๋๊ตฌ";
// ๋ฐฉ๋ฒ 1: ๋ฌธ์์ด์์ ์ง์ ํ์ฑ
var lines = csvContent.Split('\n');
string[] headers = lines[0].Split(',');
for (int i = 1; i < lines.Length; i++)
{
if (string.IsNullOrWhiteSpace(lines[i])) continue;
string[] values = lines[i].Split(',');
var record = new Dictionary<string, string>();
for (int j = 0; j < headers.Length; j++)
{
record[headers[j].Trim()] = values[j].Trim();
}
Console.WriteLine($"์ด๋ฆ: {record["์ด๋ฆ"]}, ๋์: {record["๋์"]}");
}
// ๋ฐฉ๋ฒ 2: ํ์ผ์์ ์ฝ๊ธฐ
using var fileReader = new StreamReader("data.csv", System.Text.Encoding.UTF8);
string? line;
bool isFirstLine = true;
while ((line = fileReader.ReadLine()) != null)
{
if (isFirstLine) { isFirstLine = false; continue; } // ํค๋ ์คํต
string[] fields = line.Split(',');
Console.WriteLine(string.Join(" | ", fields));
}
"ํ๊ธธ๋, ๊ฐ๋ฐ์","์์ธ, ๊ฐ๋จ๊ตฌ",30 ๊ฐ์ด ์ผํ๊ฐ ํฌํจ๋ ํ๋๋ Split(',')์ผ๋ก ์ ๋๋ก ํ์ฑ์ด ์ ๋ผ.์ด๋ฐ ๊ฒฝ์ฐ์ CsvHelper๋ฅผ ์ฐ๋ ๊ฒ ์ ๋ต์ด์ผ!
๐น CsvHelper โ CSV ํ์ฑ์ ๋ํ์
NuGet์์ CsvHelper ํจํค์ง๋ฅผ ์ค์นํ๋ฉด ๋ผ.
์ผํ ํฌํจ, ์ค๋ฐ๊ฟ ํฌํจ, ๋ฐ์ดํ ์ฒ๋ฆฌ ๋ฑ ๋ชจ๋ ์ฃ์ง ์ผ์ด์ค๋ฅผ ์๋์ผ๋ก ์ฒ๋ฆฌํด์ค!
using CsvHelper;
using CsvHelper.Configuration;
using System.Globalization;
// ๋ชจ๋ธ ํด๋์ค
public class Person
{
public string ์ด๋ฆ { get; set; }
public int ๋์ด { get; set; }
public string ์ด๋ฉ์ผ { get; set; }
public string ๋์ { get; set; }
}
// CSV ํ์ผ ์ฝ๊ธฐ โ ๊ฐ์ฒด ๋ฆฌ์คํธ
var config = new CsvConfiguration(CultureInfo.InvariantCulture)
{
HasHeaderRecord = true,
Encoding = System.Text.Encoding.UTF8,
MissingFieldFound = null // ๋๋ฝ ํ๋ ๋ฌด์
};
using var reader = new StreamReader("people.csv");
using var csv = new CsvReader(reader, config);
List<Person> people = csv.GetRecords<Person>().ToList();
foreach (var person in people)
{
Console.WriteLine($"{person.์ด๋ฆ} ({person.๋์ด}์ธ) - {person.๋์}");
}
๐ CsvHelper๋ก CSV ์ฐ๊ธฐ
// ๊ฐ์ฒด ๋ฆฌ์คํธ โ CSV ํ์ผ ์ ์ฅ
var data = new List<Person>
{
new Person { ์ด๋ฆ = "ํ๊ธธ๋", ๋์ด = 30, ์ด๋ฉ์ผ = "hong@example.com", ๋์ = "์์ธ" },
new Person { ์ด๋ฆ = "๊น์ฒ ์", ๋์ด = 28, ์ด๋ฉ์ผ = "kim@example.com", ๋์ = "๋ถ์ฐ" }
};
using var writer = new StreamWriter("output.csv", false, System.Text.Encoding.UTF8);
using var csvWriter = new CsvWriter(writer, CultureInfo.InvariantCulture);
csvWriter.WriteRecords(data);
Console.WriteLine("CSV ํ์ผ ์ ์ฅ ์๋ฃ!");
๐ ClassMap์ผ๋ก ์ปฌ๋ผ ๋งคํ ์ปค์คํฐ๋ง์ด์ง
// CSV ์ปฌ๋ผ๋ช
๊ณผ C# ์์ฑ๋ช
์ด ๋ค๋ฅผ ๋
public class PersonMap : ClassMap<Person>
{
public PersonMap()
{
Map(m => m.์ด๋ฆ).Name("Name"); // CSV์ "Name" โ ์ด๋ฆ
Map(m => m.๋์ด).Name("Age"); // CSV์ "Age" โ ๋์ด
Map(m => m.์ด๋ฉ์ผ).Name("Email"); // CSV์ "Email" โ ์ด๋ฉ์ผ
Map(m => m.๋์).Name("City"); // CSV์ "City" โ ๋์
}
}
// ClassMap ๋ฑ๋ก ํ ์ฌ์ฉ
using var csv = new CsvReader(reader, config);
csv.Context.RegisterClassMap<PersonMap>();
var people = csv.GetRecords<Person>().ToList();
๐น TextFieldParser โ .NET ๋ด์ฅ CSV ํ์
์ธ๋ถ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์์ด ์ฐ๊ณ ์ถ๋ค๋ฉด Microsoft.VisualBasic.FileIO.TextFieldParser๋ ์ข์ ์ ํ์ด์ผ!
using Microsoft.VisualBasic.FileIO;
using var parser = new TextFieldParser("data.csv");
parser.TextFieldType = FieldType.Delimited;
parser.SetDelimiters(",");
parser.HasFieldsEnclosedInQuotes = true; // ๋ฐ์ดํ ์ฒ๋ฆฌ ์๋ํ!
// ํค๋ ์ฝ๊ธฐ
string[] headers = parser.ReadFields();
while (!parser.EndOfData)
{
string[] fields = parser.ReadFields();
for (int i = 0; i < headers.Length; i++)
{
Console.Write($"{headers[i]}: {fields[i]} ");
}
Console.WriteLine();
}
๐ ํฌ๋งท ๊ฐ ๋ณํ โ JSON โ XML โ CSV
์ค๋ฌด์์๋ ํ ํฌ๋งท์ ๋ค๋ฅธ ํฌ๋งท์ผ๋ก ๋ณํํด์ผ ํ๋ ๊ฒฝ์ฐ๊ฐ ์ ๋ง ๋ง์.
API์์ JSON์ผ๋ก ๋ฐ์ ๋ฐ์ดํฐ๋ฅผ XML๋ก ์ ์ฅํ๊ฑฐ๋, CSV ๋ฐ์ดํฐ๋ฅผ JSON API๋ก ์ ์กํ๋ ์์ด์ง.
์ด๋ฐ ๋ณํ ์์
์ ๊น๋ํ๊ฒ ์ฒ๋ฆฌํ๋ ๋ฐฉ๋ฒ์ ์์๋ณด์! ๐
๐น JSON โ XML ๋ณํ
using System.Xml.Linq;
using System.Text.Json;
// ๋ฐฉ๋ฒ 1: Newtonsoft.Json ํ์ฉ (๊ฐ์ฅ ๊ฐํธ!)
// NuGet: Newtonsoft.Json
using Newtonsoft.Json;
string json = @"{
""์ง์๋ชฉ๋ก"": {
""์ง์"": [
{""์ด๋ฆ"": ""ํ๊ธธ๋"", ""๋์ด"": 30},
{""์ด๋ฆ"": ""๊น์ฒ ์"", ""๋์ด"": 28}
]
}
}";
// JSON โ XmlDocument ๋ณํ (Newtonsoft)
System.Xml.XmlDocument xmlDoc = JsonConvert.DeserializeXmlNode(json, "๋ฃจํธ");
string xmlString = xmlDoc.OuterXml;
Console.WriteLine(xmlString);
// ๋ฐฉ๋ฒ 2: ์๋ ๋ณํ (System.Text.Json + LINQ to XML)
using JsonDocument doc = JsonDocument.Parse(json);
XElement root = ConvertJsonToXml(doc.RootElement, "๋ฃจํธ");
XElement ConvertJsonToXml(JsonElement element, string name)
{
var xElement = new XElement(name);
switch (element.ValueKind)
{
case JsonValueKind.Object:
foreach (var prop in element.EnumerateObject())
xElement.Add(ConvertJsonToXml(prop.Value, prop.Name));
break;
case JsonValueKind.Array:
foreach (var item in element.EnumerateArray())
xElement.Add(ConvertJsonToXml(item, "ํญ๋ชฉ"));
break;
default:
xElement.Value = element.ToString();
break;
}
return xElement;
}
๐น XML โ JSON ๋ณํ
// Newtonsoft.Json์ผ๋ก XML โ JSON (์ด๊ฐ๋จ!)
using Newtonsoft.Json;
string xmlInput = @"
<์ง์๋ชฉ๋ก>
<์ง์>
<์ด๋ฆ>ํ๊ธธ๋</์ด๋ฆ>
<๋์ด>30</๋์ด>
</์ง์>
</์ง์๋ชฉ๋ก>";
var xmlDoc = new System.Xml.XmlDocument();
xmlDoc.LoadXml(xmlInput);
string jsonResult = JsonConvert.SerializeXmlNode(xmlDoc, Formatting.Indented);
Console.WriteLine(jsonResult);
// ์๋ ๋ณํ (LINQ to XML + System.Text.Json)
XDocument xDoc = XDocument.Parse(xmlInput);
var employees = xDoc.Root
.Elements("์ง์")
.Select(e => new
{
์ด๋ฆ = (string)e.Element("์ด๋ฆ"),
๋์ด = (int)e.Element("๋์ด")
})
.ToList();
string json = JsonSerializer.Serialize(new { ์ง์๋ชฉ๋ก = employees },
new JsonSerializerOptions { WriteIndented = true });
Console.WriteLine(json);
๐น CSV โ JSON ๋ณํ
using CsvHelper;
using System.Text.Json;
using System.Globalization;
// CSV ํ์ผ โ JSON ๋ณํ
public static string CsvToJson(string csvFilePath)
{
using var reader = new StreamReader(csvFilePath, System.Text.Encoding.UTF8);
using var csv = new CsvReader(reader, CultureInfo.InvariantCulture);
// ๋์ ์ผ๋ก ๋ ์ฝ๋ ์ฝ๊ธฐ
var records = csv.GetRecords<dynamic>().ToList();
return JsonSerializer.Serialize(records, new JsonSerializerOptions
{
WriteIndented = true
});
}
// ๋๋ Dictionary๋ก ๋ณํ
public static string CsvToJsonManual(string csvContent)
{
var lines = csvContent.Trim().Split('\n');
var headers = lines[0].Split(',').Select(h => h.Trim()).ToArray();
var records = new List<Dictionary<string, string>>();
for (int i = 1; i < lines.Length; i++)
{
var values = lines[i].Split(',');
var record = new Dictionary<string, string>();
for (int j = 0; j < headers.Length && j < values.Length; j++)
{
record[headers[j]] = values[j].Trim();
}
records.Add(record);
}
return JsonSerializer.Serialize(records, new JsonSerializerOptions
{
WriteIndented = true,
Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping
});
}
๐น JSON โ CSV ๋ณํ
using System.Text.Json;
using CsvHelper;
// JSON ๋ฐฐ์ด โ CSV ํ์ผ
public static void JsonToCsv<T>(string jsonString, string outputPath)
{
var items = JsonSerializer.Deserialize<List<T>>(jsonString);
using var writer = new StreamWriter(outputPath, false, System.Text.Encoding.UTF8);
using var csv = new CsvWriter(writer, System.Globalization.CultureInfo.InvariantCulture);
csv.WriteRecords(items);
}
// ์ฌ์ฉ ์์
string json = @"[
{""์ด๋ฆ"": ""ํ๊ธธ๋"", ""๋์ด"": 30, ""๋์"": ""์์ธ""},
{""์ด๋ฆ"": ""๊น์ฒ ์"", ""๋์ด"": 28, ""๋์"": ""๋ถ์ฐ""}
]";
JsonToCsv<Person>(json, "output.csv");
Console.WriteLine("JSON โ CSV ๋ณํ ์๋ฃ!");
โก ๊ณ ๊ธ ๊ธฐ๋ฒ โ ์ค๋ฌด์์ ๋ฐ๋ก ์ฐ๋ ํ ํฌ๋
๐น ๋น๋๊ธฐ ์ฒ๋ฆฌ (Async/Await)
ํ์ผ I/O๋ HTTP ์์ฒญ์์ ๋ฐ์ดํฐ๋ฅผ ํ์ฑํ ๋๋ ๋น๋๊ธฐ ์ฒ๋ฆฌ๊ฐ ํ์์ผ.
ํนํ ๋์ฉ๋ ๋ฐ์ดํฐ๋ฅผ ๋ค๋ฃฐ ๋ UI ์ค๋ ๋๋ฅผ ๋ธ๋กํนํ์ง ์์ผ๋ ค๋ฉด ๊ผญ ์์์ผ ํด!
using System.Net.Http;
using System.Text.Json;
// HTTP API์์ JSON ๋น๋๊ธฐ ํ์ฑ
public class ApiService
{
private readonly HttpClient _httpClient;
public ApiService(HttpClient httpClient)
{
_httpClient = httpClient;
}
public async Task<List<User>> GetUsersAsync(string apiUrl)
{
// HTTP GET ์์ฒญ
HttpResponseMessage response = await _httpClient.GetAsync(apiUrl);
response.EnsureSuccessStatusCode();
// ์คํธ๋ฆผ์ผ๋ก ์ง์ ์ญ์ง๋ ฌํ (๋ฉ๋ชจ๋ฆฌ ํจ์จ์ !)
await using Stream stream = await response.Content.ReadAsStreamAsync();
var options = new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true // ๋์๋ฌธ์ ๋ฌด์
};
return await JsonSerializer.DeserializeAsync<List<User>>(stream, options)
?? new List<User>();
}
// ๋น๋๊ธฐ ํ์ผ ์ฝ๊ธฐ + JSON ํ์ฑ
public async Task<T?> ReadJsonFileAsync<T>(string filePath)
{
await using FileStream fs = File.OpenRead(filePath);
return await JsonSerializer.DeserializeAsync<T>(fs);
}
}
๐น Source Generator ํ์ฉ (AOT ์ต์ ํ)
.NET 6+์์๋ JsonSerializerContext๋ฅผ ์ฌ์ฉํ ์์ค ์ ๋๋ ์ดํฐ ๋ฐฉ์์ผ๋ก
๋ฆฌํ๋ ์
์์ด JSON ์ง๋ ฌํ๋ฅผ ์ฒ๋ฆฌํ ์ ์์ด. AOT(Ahead-of-Time) ์ปดํ์ผ ํ๊ฒฝ์์ ํ์์ผ!
using System.Text.Json.Serialization;
// JsonSerializerContext ์ ์
[JsonSerializable(typeof(User))]
[JsonSerializable(typeof(List<User>))]
[JsonSerializable(typeof(Product))]
public partial class AppJsonContext : JsonSerializerContext { }
// ์ฌ์ฉ ์์ (๋ฆฌํ๋ ์
์์ด ๋น ๋ฅธ ์ง๋ ฌํ!)
var user = new User { Id = 1, Name = "ํ๊ธธ๋" };
// Source Generator ๋ฐฉ์
string json = JsonSerializer.Serialize(user, AppJsonContext.Default.User);
User? parsed = JsonSerializer.Deserialize(json, AppJsonContext.Default.User);
Console.WriteLine($"์ด๋ฆ: {parsed?.Name}");
๐น ๋์ฉ๋ ๋ฐ์ดํฐ ์คํธ๋ฆฌ๋ฐ ์ฒ๋ฆฌ
using System.Text.Json;
// Utf8JsonWriter๋ก ๋์ฉ๋ JSON ์คํธ๋ฆฌ๋ฐ ์์ฑ
public async Task WriteHugeJsonAsync(IEnumerable<User> users, Stream outputStream)
{
await using var writer = new Utf8JsonWriter(outputStream,
new JsonWriterOptions { Indented = false });
writer.WriteStartArray();
foreach (var user in users)
{
writer.WriteStartObject();
writer.WriteNumber("id", user.Id);
writer.WriteString("name", user.Name);
writer.WriteString("email", user.Email);
writer.WriteBoolean("isActive", user.IsActive);
writer.WriteEndObject();
// ์ฃผ๊ธฐ์ ์ผ๋ก ํ๋ฌ์ (๋ฉ๋ชจ๋ฆฌ ๊ด๋ฆฌ)
if (writer.BytesPending > 65536) // 64KB๋ง๋ค
{
await writer.FlushAsync();
}
}
writer.WriteEndArray();
await writer.FlushAsync();
}
๐น ์๋ฌ ์ฒ๋ฆฌ ํจํด
// ์์ ํ JSON ํ์ฑ ํจํด
public static T? SafeDeserialize<T>(string json, ILogger? logger = null)
{
try
{
if (string.IsNullOrWhiteSpace(json))
{
logger?.LogWarning("๋น JSON ๋ฌธ์์ด์ด ์
๋ ฅ๋์์ต๋๋ค.");
return default;
}
return JsonSerializer.Deserialize<T>(json, new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true,
AllowTrailingCommas = true, // ํํ ์ผํ ํ์ฉ
ReadCommentHandling = JsonCommentHandling.Skip // ์ฃผ์ ๋ฌด์
});
}
catch (JsonException ex)
{
logger?.LogError(ex, "JSON ํ์ฑ ์คํจ: {Path}", ex.Path);
return default;
}
}
// Result ํจํด์ผ๋ก ์๋ฌ ์ฒ๋ฆฌ
public record ParseResult<T>(bool Success, T? Data, string? ErrorMessage);
public static ParseResult<T> TryParseJson<T>(string json)
{
try
{
var data = JsonSerializer.Deserialize<T>(json);
return new ParseResult<T>(true, data, null);
}
catch (JsonException ex)
{
return new ParseResult<T>(false, default, ex.Message);
}
}
// ์ฌ์ฉ
var result = TryParseJson<User>(someJson);
if (result.Success)
Console.WriteLine($"ํ์ฑ ์ฑ๊ณต: {result.Data?.Name}");
else
Console.WriteLine($"ํ์ฑ ์คํจ: {result.ErrorMessage}");
๐๏ธ ์ฑ๋ฅ ๋น๊ต โ ์ด๋ค ๋ฐฉ๋ฒ์ด ๊ฐ์ฅ ๋น ๋ฅผ๊น?
๊ฐ์ ์์
์ด๋ผ๋ ์ด๋ค ๋ฐฉ๋ฒ์ ์ฐ๋๋์ ๋ฐ๋ผ ์ฑ๋ฅ ์ฐจ์ด๊ฐ ํฌ๊ฒ ๋ ์ ์์ด.
BenchmarkDotNet ๊ธฐ๋ฐ ์ค์ ๋ฒค์น๋งํฌ ๊ฒฐ๊ณผ๋ฅผ ์ฐธ๊ณ ํด์ ์ํฉ์ ๋ง๋ ์ ํ์ ํ์!
| ๋ฐฉ๋ฒ | ์๋ ์๋ | ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ | ์ถ์ฒ ์ํฉ |
|---|---|---|---|
| System.Text.Json (Source Gen) | ๐ ๊ฐ์ฅ ๋น ๋ฆ | ์ต์ | AOT, ๊ณ ์ฑ๋ฅ ์๋ฒ |
| System.Text.Json (Reflection) | โก ๋น ๋ฆ | ๋ฎ์ | ์ผ๋ฐ์ ์ธ .NET 5+ ์ฑ |
| Newtonsoft.Json | ๐ ๋ณดํต | ์ค๊ฐ | ๋ณต์กํ ๋ณํ, ๋ ๊ฑฐ์ |
| XDocument (LINQ to XML) | ๐ถ ๋ณดํต | ์ค๊ฐ~๋์ | ์~์ค๊ฐ XML |
| XmlReader (์คํธ๋ฆฌ๋ฐ) | โก ๋น ๋ฆ | ์ต์ | ๋์ฉ๋ XML |
| CsvHelper | โก ๋น ๋ฆ | ๋ฎ์ | ๋ณต์กํ CSV |
| StreamReader + Split | ๐ ๋น ๋ฆ | ์ต์ | ๋จ์ํ CSV |
JsonSerializerOptions๋ ์์ฑ ๋น์ฉ์ด ๋์ผ๋ static์ผ๋ก ํ ๋ฒ๋ง ๋ง๋ค์ด ์ฌ์ฌ์ฉํด!2๏ธโฃ ์คํธ๋ฆผ ์ง์ ์ฒ๋ฆฌ: ๋ฌธ์์ด๋ก ๋ณํํ์ง ๋ง๊ณ Stream์ ์ง์ JsonSerializer์ ๋๊ฒจ์ค.
3๏ธโฃ ๋์ฉ๋ XML: XDocument ๋์ XmlReader๋ฅผ ์จ์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์๊ปด!
4๏ธโฃ CSV ๋์ฉ๋: CsvHelper์ GetRecords()๋ ์ง์ฐ ํ๊ฐ(lazy evaluation)๋ฅผ ํ์ฉํด!
// โ
์ข์ ์: JsonSerializerOptions๋ฅผ static์ผ๋ก ์ฌ์ฌ์ฉ
public static class JsonHelper
{
private static readonly JsonSerializerOptions _options = new()
{
PropertyNameCaseInsensitive = true,
WriteIndented = false,
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull
};
public static T? Deserialize<T>(string json)
=> JsonSerializer.Deserialize<T>(json, _options);
public static string Serialize<T>(T obj)
=> JsonSerializer.Serialize(obj, _options);
}
// โ ๋์ ์: ๋งค๋ฒ ์ ์ต์
๊ฐ์ฒด ์์ฑ (์ฑ๋ฅ ์ ํ!)
public static T? BadDeserialize<T>(string json)
=> JsonSerializer.Deserialize<T>(json, new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true // ๋งค๋ฒ ์๋ก ์์ฑ = ๋๋ฆผ!
});
๐ ๏ธ ์ค์ ์์ โ ์ข ํฉ ๋ฐ์ดํฐ ์ฒ๋ฆฌ ํ์ดํ๋ผ์ธ
์ง๊ธ๊น์ง ๋ฐฐ์ด ๋ด์ฉ์ ์ข
ํฉํด์ ์ค์ ์
๋ฌด์์ ์ธ ์ ์๋ ๋ฐ์ดํฐ ์ฒ๋ฆฌ ํ์ดํ๋ผ์ธ์ ๋ง๋ค์ด๋ณด์!
CSV ํ์ผ์ ์ฝ์ด์ ์ฒ๋ฆฌํ๊ณ , JSON API๋ก ์ ์กํ๊ณ , ๊ฒฐ๊ณผ๋ฅผ XML๋ก ์ ์ฅํ๋ ์๋๋ฆฌ์ค์ผ. ๐ฏ
using System.Text.Json;
using System.Xml.Linq;
using CsvHelper;
using System.Globalization;
using System.Net.Http;
// ๋ฐ์ดํฐ ๋ชจ๋ธ
public record Employee(
int Id,
string Name,
string Department,
decimal Salary,
DateTime HireDate
);
public class DataPipeline
{
private readonly HttpClient _httpClient;
public DataPipeline(HttpClient httpClient)
{
_httpClient = httpClient;
}
// Step 1: CSV ์ฝ๊ธฐ
public async Task<List<Employee>> ReadFromCsvAsync(string filePath)
{
using var reader = new StreamReader(filePath, System.Text.Encoding.UTF8);
using var csv = new CsvReader(reader, CultureInfo.InvariantCulture);
return await Task.Run(() => csv.GetRecords<Employee>().ToList());
}
// Step 2: ๋ฐ์ดํฐ ์ฒ๋ฆฌ (์: ๊ธ์ฌ 10% ์ธ์)
public List<Employee> ProcessData(List<Employee> employees)
{
return employees
.Where(e => e.Salary > 0) // ์ ํจํ ๋ฐ์ดํฐ๋ง
.Select(e => e with { Salary = e.Salary * 1.1m }) // 10% ์ธ์
.OrderBy(e => e.Department)
.ThenBy(e => e.Name)
.ToList();
}
// Step 3: JSON API๋ก ์ ์ก
public async Task<bool> SendToApiAsync(List<Employee> employees, string apiUrl)
{
var json = JsonSerializer.Serialize(employees, new JsonSerializerOptions
{
WriteIndented = false,
PropertyNamingPolicy = JsonNamingPolicy.CamelCase
});
var content = new StringContent(json, System.Text.Encoding.UTF8, "application/json");
try
{
var response = await _httpClient.PostAsync(apiUrl, content);
return response.IsSuccessStatusCode;
}
catch (HttpRequestException ex)
{
Console.WriteLine($"API ์ ์ก ์คํจ: {ex.Message}");
return false;
}
}
// Step 4: XML๋ก ๊ฒฐ๊ณผ ์ ์ฅ
public async Task SaveToXmlAsync(List<Employee> employees, string outputPath)
{
var xDoc = new XDocument(
new XDeclaration("1.0", "utf-8", "yes"),
new XElement("์ง์๋ชฉ๋ก",
new XAttribute("์์ฑ์ผ์", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")),
new XAttribute("์ด์ธ์", employees.Count),
employees.Select(e => new XElement("์ง์",
new XAttribute("id", e.Id),
new XElement("์ด๋ฆ", e.Name),
new XElement("๋ถ์", e.Department),
new XElement("๊ธ์ฌ", e.Salary.ToString("N0")),
new XElement("์
์ฌ์ผ", e.HireDate.ToString("yyyy-MM-dd"))
))
)
);
await Task.Run(() => xDoc.Save(outputPath));
Console.WriteLine($"XML ์ ์ฅ ์๋ฃ: {outputPath}");
}
// ์ ์ฒด ํ์ดํ๋ผ์ธ ์คํ
public async Task RunPipelineAsync(string csvPath, string apiUrl, string xmlOutput)
{
Console.WriteLine("๐ ๋ฐ์ดํฐ ํ์ดํ๋ผ์ธ ์์...");
// 1. CSV ์ฝ๊ธฐ
var rawData = await ReadFromCsvAsync(csvPath);
Console.WriteLine($"โ
CSV ์ฝ๊ธฐ ์๋ฃ: {rawData.Count}๊ฑด");
// 2. ์ฒ๋ฆฌ
var processed = ProcessData(rawData);
Console.WriteLine($"โ
๋ฐ์ดํฐ ์ฒ๋ฆฌ ์๋ฃ: {processed.Count}๊ฑด");
// 3. API ์ ์ก
bool apiSuccess = await SendToApiAsync(processed, apiUrl);
Console.WriteLine($"โ
API ์ ์ก: {(apiSuccess ? "์ฑ๊ณต" : "์คํจ")}");
// 4. XML ์ ์ฅ
await SaveToXmlAsync(processed, xmlOutput);
Console.WriteLine("๐ ํ์ดํ๋ผ์ธ ์๋ฃ!");
}
}
// ์คํ
var pipeline = new DataPipeline(new HttpClient());
await pipeline.RunPipelineAsync(
csvPath: "employees.csv",
apiUrl: "https://api.example.com/employees",
xmlOutput: "result.xml"
);
๐ก ๋ง๋ฌด๋ฆฌ โ ์ค๋ฌด์์ ๊ผญ ๊ธฐ์ตํ ๊ฒ๋ค
์ฌ๊ธฐ๊น์ง JSON, XML, CSV ํ์ฑ๊ณผ ๋ณํ์ ํต์ฌ์ ๋ชจ๋ ์ดํด๋ดค์ด!
๋ง์ง๋ง์ผ๋ก ์ค๋ฌด์์ ๊ผญ ๊ธฐ์ตํด์ผ ํ ๋ฒ ์คํธ ํ๋ํฐ์ค๋ค์ ์ ๋ฆฌํด์ค๊ฒ. ๐
Encoding.UTF8์ ํญ์ ๋ช
์ํด์ค.ํนํ ํ๊ธ ๋ฐ์ดํฐ๊ฐ ์์ ๋ ์ธ์ฝ๋ฉ์ ๋น ๋จ๋ฆฌ๋ฉด ๊นจ์ง ํ์์ด ๋ฐ์ํด!
?? throw new InvalidOperationException() ํจํด์ด๋nullable reference type์ ํ์ฉํด์ null ์์ ์ฑ์ ํ๋ณดํด!
JsonSerializer.DeserializeAsync(stream)์ด๋ XmlReader๋ฅผ ํ์ฉํด!
์ค๋ฌด ๋ฐ์ดํฐ๋ ํญ์ CsvHelper๋ TextFieldParser๋ฅผ ์จ!
XML: ์ ํ๋ก์ ํธ โ XDocument + LINQ / ๋์ฉ๋ โ XmlReader / ๊ฐ์ฒด ๋งคํ โ XmlSerializer
CSV: ๋จ์ โ StreamReader + Split / ๋ณต์ก โ CsvHelper / ๋ด์ฅ๋ง โ TextFieldParser
๋ฐ์ดํฐ ํ์ฑ ์ค๋ ฅ์ C# ๊ฐ๋ฐ์๋ก์์ ๊ธฐ๋ณธ๊ธฐ ์ค์์๋ ํต์ฌ์ด์ผ.
์ด ๊ธ์์ ๋ค๋ฃฌ ๊ธฐ๋ฒ๋ค์ ์ค์ ํ๋ก์ ํธ์ ์ ์ฉํด๋ณด๋ฉด์ ์์ ์ตํ๋ ๊ฒ ๊ฐ์ฅ ์ค์ํด!
ํน์ C# ๋ฐ์ดํฐ ์ฒ๋ฆฌ ๊ด๋ จ ํ๋ก์ ํธ๋ฅผ ์งํํ๋ค๊ฐ ๋งํ๋ ๋ถ๋ถ์ด ์๋ค๋ฉด,
์ฌ๋ฅ๋ท์์ C# ์ ๋ฌธ ๊ฐ๋ฐ์์ ๋์์ ๋ฐ์๋ณด๋ ๊ฒ๋ ์ข์ ๋ฐฉ๋ฒ์ด์ผ.
๋ค์ํ ์ค๋ ฅ์๋ค์ด ๋ฐ์ดํฐ ํ์ฑ๋ถํฐ ์ํคํ
์ฒ ์ค๊ณ๊น์ง ๋์์ ์ค ์ ์๊ฑฐ๋ ! ๐
๊ด๋ จ ํค์๋
๋๊ธ ์์ฑ
์ด ๊ธ์ ๋ํ ์ฌ๋ฌ๋ถ์ ์๊ฐ์ ๋ค๋ ค์ฃผ์ธ์
๋ก๊ทธ์ธ์ด ํ์ํฉ๋๋ค
๋๊ธ์ ์์ฑํ๋ ค๋ฉด ๋จผ์ ๋ก๊ทธ์ธํด์ฃผ์ธ์.
๋๊ธ 0
์ง์์ธ์ ์ฒ - ์ง์ ์ฌ์ฐ๊ถ ๋ณดํธ ๊ณ ์ง
์ง์ ์ฌ์ฐ๊ถ ๋ณดํธ ๊ณ ์ง
- ์ ์๊ถ ๋ฐ ์์ ๊ถ: ๋ณธ ์ปจํ ์ธ ๋ ์ฌ๋ฅ๋ท์ ๋ ์ AI ๊ธฐ์ ๋ก ์์ฑ๋์์ผ๋ฉฐ, ๋ํ๋ฏผ๊ตญ ์ ์๊ถ๋ฒ ๋ฐ ๊ตญ์ ์ ์๊ถ ํ์ฝ์ ์ํด ๋ณดํธ๋ฉ๋๋ค.
- AI ์์ฑ ์ปจํ ์ธ ์ ๋ฒ์ ์ง์: ๋ณธ AI ์์ฑ ์ปจํ ์ธ ๋ ์ฌ๋ฅ๋ท์ ์ง์ ์ฐฝ์๋ฌผ๋ก ์ธ์ ๋๋ฉฐ, ๊ด๋ จ ๋ฒ๊ท์ ๋ฐ๋ผ ์ ์๊ถ ๋ณดํธ๋ฅผ ๋ฐ์ต๋๋ค.
- ์ฌ์ฉ ์ ํ: ์ฌ๋ฅ๋ท์ ๋ช ์์ ์๋ฉด ๋์ ์์ด ๋ณธ ์ปจํ ์ธ ๋ฅผ ๋ณต์ , ์์ , ๋ฐฐํฌ, ๋๋ ์์ ์ ์ผ๋ก ํ์ฉํ๋ ํ์๋ ์๊ฒฉํ ๊ธ์ง๋ฉ๋๋ค.
- ๋ฐ์ดํฐ ์์ง ๊ธ์ง: ๋ณธ ์ปจํ ์ธ ์ ๋ํ ๋ฌด๋จ ์คํฌ๋ํ, ํฌ๋กค๋ง, ๋ฐ ์๋ํ๋ ๋ฐ์ดํฐ ์์ง์ ๋ฒ์ ์ ์ฌ์ ๋์์ด ๋ฉ๋๋ค.
- AI ํ์ต ์ ํ: ์ฌ๋ฅ๋ท์ AI ์์ฑ ์ปจํ ์ธ ๋ฅผ ํ AI ๋ชจ๋ธ ํ์ต์ ๋ฌด๋จ ์ฌ์ฉํ๋ ํ์๋ ๊ธ์ง๋๋ฉฐ, ์ด๋ ์ง์ ์ฌ์ฐ๊ถ ์นจํด๋ก ๊ฐ์ฃผ๋ฉ๋๋ค.
์์ง ๋๊ธ์ด ์์ต๋๋ค.