개발꿈나무
[C# 교과서] 35. C# 확장 기능(10) - 스트림과 파일 입출력 본문
스트림과 파일 입출력
프로그램 코드에서 작성된 데이터를 목적에 따라 영구적으로 보관해야 할 때가 있는데, 이때는 파일이나 데이터베이스에 저장한다. 파일에 데이터를 저장하고 이를 사용해보자.
System.IO 네임스페이스
C#에서 파일에 대한 입력과 출력을 담당하는 네임스페이스는 System.IO이며, 수많은 파일과 디렉터리 관련 클래스를 제공한다.
- File.Exists(): 지정된 경로에 파일이 있으면 true, 없으면 false 반환
- new DirectoryInfo().Parent.FullName: 지정된 경로의 부모 폴더 값 반환
- Path.GetDirectoryName(): 지정한 경로의 디렉터리 값 반환
- Path.Combile(): 졍로 2개를 합치거나 경로와 파일 이름을 묶어서 반환
- Directory.Exists(): 지정된 디렉터리가 있는지 확인
- Directory.CreateDirectory(): 디렉터리 생성
- Directory.Delete(): 디렉터리 삭제
- Path.GetFileName(): 파일 이름 추출
- Path.GetExtension(): 파일 확장자 추출
- File.Copy(): 파일 복사
- File.Move(): 파일 이동
- Directory.GetFiles(): 지정된 경로의 파일 이름 리스트를 문자열 배열로 반환
- File.ReadAllText(): 텍스트 파일 읽기
- File.WriteAllText(): 텍스트 파일 쓰기
- File.ReadAllLines(): 텍스트 파일의 모든 줄을 읽어 문자열 배열로 반환
- File.WriteAllLines(): 문자열 배열을 줄 단위로 텍스트 파일에 저장
- File.AppendAllText(): 텍스트 파일에 내용 추가
- File.AppendAllLines(): 컬렉션 형태의 문자열 추가
- File.ReadAllBytes(): 바이너리 파일 읽기
- File.ReadAllBytes(): 바이너리 파일 쓰기
File 클래스와 Stream 클래스
- File 클래스: File 클래스는 사용하기 편하지만 모든 파일 내용을 다 읽어 처리하기 때문에 대용량 파일을 처리할 때는 메모리를 관리하기 어렵다.
- Stream 클래스: Stream 클래스는 모든 데이터를 메모리에 올려 두지 않고 사용하기 때문에 대용량 파일 처리에 효과적이다.
문자열에서 파일 이름 추출하기
using System;
class GetFileNameDemo
{
static void Main()
{
//[Q] 아래 전체 경로가 입력되었을 때 파일명과 확장자 추출
//[1] Input
string dir = "C:\\Website\\RedPlus\\images\\test.gif";
string fullName = String.Empty;
string name = "";
string ext = name;
//[2] Process
// 전체파일명: 마지막 \\ 위치값 + 1한 위치부터 마지막까지 검색
fullName = dir.Substring(dir.LastIndexOf('\\') + 1);
name = fullName.Substring(0, fullName.LastIndexOf('.'));
ext = fullName.Substring(fullName.LastIndexOf('.') + 1);
//[3] Output
Console.WriteLine($"전체 파일명: {fullName}");
Console.WriteLine($"순수 파일명: {name}");
Console.WriteLine($"확장자: {ext}");
}
}
/*
전체 파일 이름 : test.gif
순수 파일 이름 : test
확장자 : gif
*/
substring(n, m)은 n부터 m개의 문자를 읽어오는 메소드로,
매개변수가 하나만 들어온다면 해당 번째 문자부터 마지막 문자까지 읽어온다.
Path 클래스로 파일 이름 및 확장자, 폴더 정보 얻기
var dir = "C:\\Website\\RedPlus\\images\\test.gif";
Path.GetFileName(dir) //test.gif
Path.GetFileNameWithoutExtension(dir) //test
Path.GetExtension(dir) //.gif
Path.GetDirectoryName(dir) //C:\\Website\\RedPlus\\images
Path.GetFullPath(dir) //C:\\Website\\RedPlus\\images\\test.gif
다음 코드를 C# 인터렉티브(Ctrl + E + E)에서 실행해보면 주석과 같은 결과가 나올 것이다.
파일과 디렉터리 관련 클래스
파일을 생성하고 삭제하는 일반적인 절차는 다음과 같다.
- StreamWriter 클래스를 사용하여 텍스트 파일 쓰기
- StreamReader 클래스를 사용하여 텍스트 파일 읽기
- File과 FileInfo 클래스로 파일 정보 얻기
- Directory와 DirectoryInfo 클래스로 폴더 정보 얻기
텍스트 파일을 만드록 문자열 저장하기
윈도 운영 체제의 C 드라이브에 Temp 폴더를 경로로 설정했지만 개인의 실행환경에 맞춰 경로를 변경하면 된다.
using System;
using System.IO;
class StreamWriterWriteLineDemo
{
static void Main()
{
string data =
"안녕하세요.\r\n반가습니다." + Environment.NewLine + "또 만나요.";
//[1] StreamWriter 클래스를 사용하여 파일 생성
// C 드라이브에 Temp 폴더 미리 생성해야 함
StreamWriter sw = new StreamWriter("C:\\Temp\\Test.txt");
//[2] Write() 메서드 : 저장
sw.WriteLine(data);
//[3] StreamWrite 개체를 생성했으면 반드시 닫기
sw.Close();
//[4] 메모리 해제
sw.Dispose();
}
}
코드를 실행하면 C 드라이브의 Temp 폴더에 Test.txt 파일이 만들어지고 data 변수에 지정된 문자열 값이 저장된다.
문자열의 \r\n 또는 Environment.NewLine 값은 텍스트 파일에서 줄 바꿈을 나타낸다.
[1]의 StreamWriter 같은 파일 처리 관련 클래스의 인스턴스를 생성하고 사용했다면, 반드시 [3]. [4]처럼 닫기와 해제
작업을 해주어야 한다.
텍스트 파일의 내용을 읽어 출력하기
using System;
using System.IO;
class StreamReaderReadToEndDemo
{
static void Main()
{
//[1] StreamReader 클래스로 텍스트 파일 읽기
StreamReader sr = new StreamReader(@"C:\Temp\Test.txt");
//[2] ReadToEnd() 메서드로 텍스트 파일의 내용 읽어 콘솔에 출력하기
Console.WriteLine("{0}", sr.ReadToEnd()); // 전체 읽어오기
//[3] 사용 후 파일 닫고 메모리 정리하기
sr.Close();
sr.Dispose();
}
}
C드라이버의 Temp 폴더에 Test.txt라는 파일이 있다는 가정하에 코드를 작성하였다.
해당 경로에 텍스트 파일을 추가하던가, 자신의 텍스트 파일 경로로 바꿔 코드를 실행하면 된다.
[1]의 StreamReader 같은 파일 처리 관련 클래스의 인스턴스를 생성하고 사용했다면, 반드시 [3]. [4]처럼 닫기와 해제
작업을 해주어야 한다.
텍스트 파일 정보 얻기
using System;
using System.IO;
class FileAndFileInfo
{
static void Main()
{
string file = "C:\\Temp\\Test.txt";
//[1] File 클래스: 정적 멤버 제공
if (File.Exists(file)) // 파일이 있다면.
{
Console.WriteLine("{0}", File.GetCreationTime(file));
File.Copy(file, "C:\\Temp\\Test2.txt", true); // 파일 복사 테스트
}
//[2] FileInfo 클래스: 인스턴스 멤버 제공
FileInfo fi = new FileInfo(file);
if (fi.Exists) // 파일이 존재한다면,
{
Console.WriteLine($"{fi.FullName}"); // 파일명 출력
}
}
}
/*
2022-01-25 오후 14:14:56
C:\TEMP\Test.txt
*/
C드라이버의 Temp 폴더에 Test.txt라는 파일이 있다는 가정하에 코드를 작성하였다.
해당 경로에 텍스트 파일을 추가하던가, 자신의 텍스트 파일 경로로 바꿔 코드를 실행하면 된다.
폴더 정보 얻기
using System;
using System.IO;
class DirectoryAndDirectoryInfo
{
static void Main()
{
string dir = "C:\\";
//[1] Directory 클래스
if (Directory.Exists(dir))
{
Console.WriteLine("[1] C 드라이브의 모든 폴더 목록을 출력");
foreach (string folder in Directory.GetDirectories(dir))
{
Console.WriteLine($"{folder}");
}
}
//[2] DirectoryInfo 클래스
DirectoryInfo di = new DirectoryInfo(dir + "Temp\\");
if (di.Exists)
{
Console.WriteLine("[2] C 드라이브의 Temp 폴더의 모든 파일 목록 출력");
foreach (var file in di.GetFiles())
{
Console.WriteLine($"{file}");
}
}
}
}
Directory 또는 DirectoryInfo 클래스의 GetDerectories() 메서드는 전체 디렉터리 리스트를 보여주고,
GetFiles() 메서드는 전체 파일 리스트를 보여준다.
텍스트 데이터를 컬렉션 데이터로 가져오기
C드라이브 Temp 폴더에 Src.txt 파일이 있고, 그 파일의 내용이 다음과 같다고 가정한 후 코드를 작성해보자.
홍길동,112,2019-09-01,1234
백두산,114,2020-10-02,2345
한라산,119,2021-11-03,3456
C:\Temp\Src.txt 파일의 내용
using System;
using System.Collections.Generic;
namespace DotNet
{
public class Record
{
public string Name { get; set; }
public string PhoneNumber { get; set; }
public DateTime BirthDate { get; set; }
public string AuthCode { get; set; }
}
class TextToCollection
{
static void Main()
{
//[1] 텍스트 파일 읽기
string[] lines =
System.IO.File.ReadAllLines(
@"C:\Temp\src.txt", System.Text.Encoding.Default);
foreach (var line in lines)
{
Console.WriteLine(line);
}
//[2] 문자열 배열의 정보를 컬렉션 형태의 개체에 담기
List<Record> records = new List<Record>();
foreach (var line in lines)
{
string[] splitData = line.Split(',');
records.Add(
new Record
{
Name = splitData[0],
PhoneNumber = splitData[1],
BirthDate = Convert.ToDateTime(splitData[2]),
AuthCode = splitData[3]
});
}
//[3] 한개 데이터만 출력해보기
Console.WriteLine(records[0]?.Name ?? "데이터가 없습니다.");
}
}
}
구분자로 콤마를 사용하는 텍스트 파일의 데이터를 읽어 List<T> 형태의 C# 컬렉션으로 변환한다.
[1]에서 파일 내용을 ReadAllLines() 메서드로 한 줄씩 읽어 lines 리스트에 담은 후 [2]에서 한 줄을 콤마(,)를 구분자로
끊어 splitData 리스트에 담아 List<Record> 형태에 저장한다.
<Reference>
'C# 기초' 카테고리의 다른 글
[C# 교과서] 37. C# 확장 기능(12) - 네트워크 프로그래밍 (0) | 2022.01.27 |
---|---|
[C# 교과서] 36. C# 확장 기능(11) - XML과 JSON (0) | 2022.01.26 |
[C# 교과서] 34. C# 확장 기능(9) - 인메모리 데이터베이스 프로그래밍 (0) | 2022.01.26 |
[C# 교과서] 33. C# 확장 기능(8) - 비동기 프로그래밍 (0) | 2022.01.26 |
[C# 교과서] 32. C# 확장 기능(7) - 스레드 (0) | 2022.01.25 |