C#에서 구조체 파일을 읽어 처리하는 간단한 예제이다.
구조체 바이너리 파일은 C++ MFC로 제작이 되어 있었다.
C++ 구조체는 아래와 같다.
typedef struct {
TCHAR Name[20];
TCHAR ID[20];
TCHAR Passwd[20];
uint Grade;
} stUserInfo;
위와 같은 구조체로 만들어지 바이너리 파일을 C#에서 읽어 클래스 리스트에 넣도록 처리 예정이다.
C#에서는 아래와 같은 구조체가 C++ 구조체와 같은 모습니다.
[Serializable]
[StructLayout(LayoutKind.Sequential)]
public struct UserInfo
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
public char[] Name;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
char[] ID;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
char[] Passwd;
uint nGrade;
}
public class CUserInfo
{
public string Name { get; set; }
public string ID { get; set; }
public string Passwd { get; set; }
public uint Grade { get; set; }
public CUserInfo()
{
Grade = 0;
}
}
C#에서는 MarshalAs를 이용해서 배열의 크기를 지정할 수 있다.
아래 소스는 바이너리를 읽어서 클래스 리스트에 추가하는 예제 함수이다.
private void buttonTest_Click(object sender, EventArgs e)
{
UserInfo user = new UserInfo();
//구조체 크기를 확인 한다.
int useSize = Marshal.SizeOf(user);
using (FileStream fs2 = new FileStream("sample.dat", FileMode.Open))
{
int size = (int)fs2.Length; //파일 크기를 구한다.
int nCount = size / useSize;//파일 크기를 구조체 크기로 나눠 구조체 개수 확인
byte[] buff = new byte[40]; //임시 버퍼
for (int i = 0; i < nCount; i++)
{
CUserInfo user2 = new CUserInfo(); //클래스 생성
Array.Clear(buff, 0, buff.Length); //버퍼 초기화
int n = fs2.Read(buff, 0, 40); //40바이트 바이너리 읽기
user2.Name = Encoding.Unicode.GetString(buff); //TCHAR 유니코드 변환
user2.Name = user2.Name.Substring(0, user2.Name.IndexOf('\0')); //널 이후 제거
Array.Clear(buff, 0, buff.Length);
n = fs2.Read(buff, 0, 40);
user2.ID = Encoding.Unicode.GetString(buff);
user2.ID = user2.ID.Substring(0, user2.ID.IndexOf('\0'));
Array.Clear(buff, 0, buff.Length);
n = fs2.Read(buff, 0, 40);
user2.Passwd = Encoding.Unicode.GetString(buff);
user2.Passwd = user2.Passwd.Substring(0, user2.Passwd.IndexOf('\0'));
Array.Clear(buff, 0, buff.Length);
n = fs2.Read(buff, 0, 4);
user2.nGrade = BitConverter.ToUInt32(buff, 0);
if (user2.Name.Length == 0) continue;
UserInfoList.Add(user2);
}
}
}
바이트 Array를 초기화는 아래와 같은 방식으로 처리를 한다.
Array.Clear(buff, 0, buff.Length);
바이너리를 string으로 컨버트 하는 것은 Encoding 클래스를 이용한다.
user2.Name = Encoding.Unicode.GetString(buff);
구조체가 TCHAR으로 unicode이기 때문에 위와 같이 컨버트를 진행한다.
스트링에 쓰레기 값이 있으면 삭제를 하기 위해서 Substring를 처리하였다.
user2.Name = user2.Name.Substring(0, user2.Name.IndexOf('\0'));
첫번째 null 값이 나오면 그 이후로 삭제를 한다.
위와 같은 방식으로 바이너리를 읽어서 클래스에 넣도록 처리를 한다.
'.NET' 카테고리의 다른 글
Team Foundation Server 버전 제어" 경고 메시지 제거 방법 (0) | 2023.04.20 |
---|---|
C# split 사용 방법 (0) | 2023.01.19 |
Codejock RibbonBar 예제 및 CXTPControlEdit spin message (0) | 2022.07.15 |
Telerik GridViewSpreadExport 이용 방법 (0) | 2022.06.27 |
Telerik RadGridView drag and drop 할 때 row index 확인 방법 (0) | 2022.06.27 |