작업을 하다보니 4GB 크기가 넘는 파일을 다루어야 할 일이 생겼네요.
윈도우즈 커널에 _hread, _hwrite 등의 숨겨진 API가 제공되지만..
이런거 찾아다가 처리하기가 여간 귀찬아서.. ㅎㅎ;

대형 파일을 그냥 fopen, open, OpenFile 등등.. 어떤 API로 처리하든지
그냥 읽고 쓰기는 가능합니다.
(단, 이 방법을 사용하시더라도 fseek, lseek는 불가능합니다.
 파일을 seek해야 할 경우는 처음에 이야기 처럼 kernel에 숨겨진 위의 함수들을
 찾아서 사용하시던지, Visual Studio 2005 이상 버전을 사용하세요.

http://support.microsoft.com/kb/q100513/
위의 주소는 MS의 KB로 Visual Basic에서 대형파일을 어떻게 처리하는지에
대한 내용입니다. 내용을 보시고 VC로 포팅하는건 ~~
)



단지, 크기를 읽을 때 문제가 발생하죠..
Visual Studio 2005 이상 버전에서는 64비트 크기를 지원하는 새로운
API들이 제공되니 그냥 그걸 쓰시면 되고...

저는 몇몇 가지를 빼곤 대부분 Visual Studio 6.0을 사용하는 관계로, 6.0을 사용하시는
분들에게만 해당되는 내용이 될것입니다.

아래는 데브피아에 올라온 원문입니다.

 4.2기가 바이트 이상의 파일을 읽고 싶습니다. [답을 찾았습니다.]  | VC++ 일반 2007-04-09 오전 11:07:43
김태권 (jukyou)  김태권님께 메시지 보내기김태권님을 내 주소록에 추가합니다.김태권님의 개인게시판 가기 번호: 650715   / 평점:  (9.0)  / 읽음:80

안녕하십니까? 이전에 제 우매한 질문에 여러분께서 답변을 해주셔셔 감사드린다는 말씀 전해 드립니다.


저번 주 주말에 답을 찾아서 답을 올립니다.


강태호 (cartarsis) 님께서 답변 주신 내용과 MSDN을 읽어 보고 해결하였습니다.

우선 4.2기가 바이트 이상의 파일을 읽어야하는 상황이 있으신 분들을 위해 글을 남겨 놓습니다.



소스는 아래와 같습니다.


HANDLE hFile;

unsigned long nSizeHigh = 0;

unsigned long nSizeLow = 0;

__int64 nSize = 0;

hFile = CreateFile(szFileName, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

nSizeLow = GetFileSize(hFile, &nSizeHigh);

nSize = nSizeHigh;

nSize <<= 32;

nSize |= nSizeLow;

TRACE("Size : %I64d\n", nSize);


좋은 하루 되세요~~


그럼 이만 줄입니다.

업무에 필요해서 파일의 버전을 읽어 오려다 보니.. MSDN에서 다음과 같은 함수를 찾을 수 있었다.
GetFileVersionInfoSize
GetFileVersionInfo
VerQueryValue
이 세가지 함수를 조합하여, 실행파일(dll. exe, etc..)에 포함된 표준 버전 정보를 읽을 수 있다.



그런데 하나씩 코드를 짜다보니, 분명 누군가 만들어 놓은게 있을 꼬야.. 하고 찾아보니
1998년 4월 MSJ에 이미 잘 만들어진 코드가 올라와 있더라 ㅎㅎ;
http://www.microsoft.com/msj/0498/c0498.aspx

설명도 잘 나왔고, 샘플까지.. ㅎㅎ;

원문 소스 중에.. 다음 함수의 일부 구문이 변경되었다.
[당근 원문은 보존하고..]
BOOL CModuleVersion::GetFileVersionInfo(LPCTSTR modulename)
원래는 시스템 이미지에 매핑된 실행파일만 읽도록 되어있는 것을..
일반 파일도 읽을 수 있도록 하였다.


 FTP에서의 파일 업로드   |  1999-12-27
권진호 (crowback )  권진호님께 메시지 보내기권진호님을 내 주소록에 추가합니다.권진호님의 개인게시판 가기 번호: 621   / 평점:  (9.0)  / 읽음:4,512

까막입니다. ^^

어떤 분이 FTP에서 파일 업로드 기능을 부탁하셨길래 올립니다.

아주 간단하게 FTP 접속 부분과
파일 전달 부분만 구현 한 것입니다.

-------------------------------------------------------------------
CFtpConnection* ftpCon = NULL;
CInternetSession* session;
BeginWaitCursor();
session = new CInternetSession(_T("My Session"));
try
{
 ftpCon = session->GetFtpConnection(IP, ID, Pass);
 // 여기서 IP, ID, Pass는 다들 아시겠죠 ^^;
}
catch(CInternetException* e)
{
 EndWaitCursor();
 MessageBeep(0xFFFFFFFF);
 e->ReportError();
 ftpCon = NULL;
 session->Close();
 delete session ;
 e->Delete();
 return FALSE;
}

EndWaitCursor();
// 현재 연결된 계정의 루트 패스를 구하는 부분입니다.
CString OriginFTPDir;
ftpCon->GetCurrentDirectory(OriginFTPDir);
CString Server = OriginFTPDi+name;  // 서버에서 받을 패스와 파일 이름
CString Client = cszFolderPath+name;// 보낼 파일의 패스와 파일 이름
try
{
 ftpCon->PutFile(Client, Server);
}
catch(CInternetException* e)
{
 EndWaitCursor();
 MessageBeep(0xFFFFFFFF);
 e->ReportError();
 e->Delete();
}
EndWaitCursor();

 FlashWindow()를 이용한 아이콘 껌뻑이기   |  2000-04-21
권진호 (crowback )  권진호님께 메시지 보내기권진호님을 내 주소록에 추가합니다.권진호님의 개인게시판 가기 번호: 938   / 평점:  (-)  / 읽음:851
까막임니다...

어떤 프로그램이 셑업이나 파일 다운로드가 끝나면...
밑에 작업 윈도우(트레이 윈도운가?)에 프로그램 이름들어간 아이콘들이 쫙 떠있자나여?

근데.. 어떤걸 보면.. 이게 무신 메시지를 보내느라 그러는지.. 파란색으로 껌뻑 껌뻑 하자나여?

전 이놈이 왜 껌뻑 거릴까? 생각해 봤더니.. 무신 작업이 끝났다는걸 사용자에게 알리기 위해서 그러는 거래여...

그래서 그걸 구현해 봤어여... 정말 시버여..

여러분들도 이제 넣어봐여.. 금방 넣을 수 있을겁니다..

미니마이즈 버튼을 눌러서 아이콘화 시키면 껌뻑 거려여... ^^

 [심플] 간단한 음성채팅 풀소스  | WinSock 2000-08-21 오전 7:31:28
권진호 (crowback )  권진호님께 메시지 보내기권진호님을 내 주소록에 추가합니다.권진호님의 개인게시판 가기 번호: 2294   / 평점:  (-)  / 읽음:5,408
까막입니다..

열심히 설명를 달았었는데.. 업로드 하니까..헤그덕 --;;; 날라가버리는 군여..

환경만 간단히 다시 설명을 달겠습니다.

프로토타입(일단 동작을 중시)으로 만들었던것이라 코덱은 PCM을 그대로 씁니다.
다이렉트 엑스를 이용한 관계로 NT에선 동작이 않됩니다.
(그때 왜 다이렉트X를 썼는지 지금은이해가 않됨 --;;;)

코덱을 변경하실라믄.. 녹음하는 부분에서 코덱 정보를 읽어 오는 부분을 쩜
수정하셔야 됩니다.

참고로, GSM 13Kbps는 윈98이상에서 지원되구여..
G.723.1은 5.6kbps & 6.3kbps는 윈2000이상에서 그냥 지원해줍니다.

맘에 드시는걸로 골라쓰세여..

[요청자료] Frame(SDI' MDI) 내부에 머무르는 모달리스 다이알로그  | VC++ 일반 2000-11-10 오후 5:13:31
권진호 (crowback )  권진호님께 메시지 보내기권진호님을 내 주소록에 추가합니다.권진호님의 개인게시판 가기 번호: 3171   / 평점:  (-)  / 읽음:2,861
까막임돠...

SDI나 MDI로 프로그램을 제작할 경우..
모달리스 다이알로그가 프레임 밖으로 벗어 나는 경우에 대하여
이를 막을 수 있는 방법에 대한 질문이 여러번 중복되어 들어 와서 자료로
올립니다.

실제 모달리스 다이알로그의 행동반경이 MDI에서의 차일드 프레임처럼
Frame내부의 뷰 안에 머물도록 하였습니다.

그럼 도움이 되었으면 합니다.

 [답변][까막] 썸네일 1차 완성판이 나왔습니다.. *^^* 2001-02-12 오후 12:41:58
권진호 (crowback )  권진호님께 메시지 보내기권진호님을 내 주소록에 추가합니다.권진호님의 개인게시판 가기 번호: 4418   / 평점:  (-)  
안냐세염.. 까막임돠..

1차 완성판이 나왔습니다. 지적해주신 문제도 조금 수정하구여..

탐색트리, 썸네일, 이미지뷰어 모두 일단 올렸구여..
특별한 동작상의 문제는 없습니다.

속도 문제를 위하여. 쓰레드나 메시지 펌핑은 하지 않았습니다.

이미지 한 100개정도를 읽어 들이는데 걸리는 시간은 시스템에 따라 다르겠지만
ACDSee보다는 쫌 빠르군여.. --;
(당근 지원하는 포멧이 간단한거만 하니까 -_-;)

추가된 기능은 이미지뷰어를 넣었다는 것이구여..
(역시 무지 심플안 이미지뷰어...)

썸네일에 대한 파일정보 툴팁을 넣어봤습니다.

그럼 이만..


아래 요청 사항이 있으셔서, 6.0과 2008로 컴파일 되도록 급수정 하였습니다.
전체 소스는 달라진건 없고, 6.0에만 있는 기능이 있어서, 공용으로 쓰이도록 수정하였습니다.

 [까막] 고속 추가 전용 - 리스트 컨트롤   | VC++ 컨트롤관련 2002-08-07 오전 11:57:17
까막 (crowback)  까막님께 메시지 보내기까막님을 내 주소록에 추가합니다.까막님의 개인게시판 가기 번호: 12923   / 평점:  (-)  / 읽음:2,929
MFC Virtual List Control -  Andrew Small by codeguru site;
먼저 여기 사용된 부분은 코드구루의 앤드류 스몰의 자료를 수정한 것입니다.
앤드류의 소스는 CLabelItem 클래스를 사용자가 직접 수정하거나, 데이터를 삽입할 때마가 불필요한 코딩이
필요하고, 또한 데이터를 한꺼번에 삽입하는것만 가능하도록 설계되어 있어 불편한 점이 조금 있습니다.

위의 소스를 수정하여.. Insert 없이 Add 전용의 고속 리스트 컨트롤을 만들어 보았습니다.
이러한 리스트는 수시로 없데이트 되는 데이터가 아닌, 로그 값이나 특정 수치값을 계속적으로 쌓아 놓는
구조에 알맞습니다.
만약 인터넷 트레픽을 수치상으로 시간과 장소, 대역폭, 사용데이트 등을...
시간대별로 계속 쌓아서 감시를 한다던가.. 하는 것.. 혹은...

여러군대에서 발생한 자료를 시간대 별로 한꺼번에 몰아서 데이터를 읽어 와 리스트에 쌓는다던가 하는
작업에 맞게 구성되었습니다.

원래의 InsertItem() 를 막고, AddItem() 함수로 대치하였습니다.
SetItemText() 함수와 GetItemText() 함수는 그대로 적용됩니다.
DeleteItem()는 삭제되었고,
DeleteAllItems() 함수도 그대로 적용됩니다.

테스트 결과 3개의 컬럼이고, 각각 10여바이트 정도의 문자열을 텍스트를 갖는경우.
약 20000 개 정도의 데이터를 삽입하는데 걸리는 시간은 P3 933, RAM 256, Release Mode에서
삽입과 화면 업데이트까지 약 0.7초 정도 걸립니다.

각각 컬럼별로 헤더에서 오름차순 정렬 혹은 내림차순 정열은 각각 0.2-0.3초 정도 소요됩니다.

물론 레포트 타입 전용입니다.
이미지 리스트도 지원하지 않습니다.

그럼 이만..

 [까막] 코딩으로 휴지통 복구하기..  | ActiveX/COM 2003-11-04 오후 6:16:46
까막 (crowback)  까막님께 메시지 보내기까막님을 내 주소록에 추가합니다.까막님의 개인게시판 가기 번호: 16893   / 평점:  (-)  / 읽음:1,749

질문에 답변 하나 달으려다 엄청난 시간이 날라갔네요. 조만간에 모가지가 될지도 ㅡㅜ;


휴지통에 보내기는 많이 보내봤는데.. 휴지통에 있는 넘을 복구하는 방법은 Undocumented라.. MSDN을

찾아봐도 껀덕지 나오는게 없더군요..


결국 쉘폴더를 불러서, 아이템을 얻고, 해당 아이템의 숏컷 핸들러를 얻은다음 Invoke 해주는

방법을 취했습니다.


동작은 잘되더군요..


1. 휴지통의 IShellFolder2 인터페이스를 얻어 온다.

2. IShellFolder2::EnumObjects() 를 이용하여 IEnumIDList 값을 긁어 들인다.

3. IEnumIDList::Next() 메서드를 이용하여, 개별적인 ITEMIDLIST 값들을 하나씩 읽어 온다.

4. 각각 읽어 온넘들을 pidl 이라 치면, 해당하는 IContextMenu 인터페이스를 얻는다.

5. IContextMenu::QueryContextMenu, IContextMenu::GetCommandString, IContextMenu::InvokeCommand

   메서드들을 적당한 인자를 주어 호출하여, 선택된 아이템을 복구한다.


대략 위와 같은 구조로 동작하구요..

 

참고 사항으로

 

휴지통에 떤지기 : SHFileOperation

휴지통을 비우기 : SHEmptyRecycleBin

휴지통에 들은 파일 갯수와 크기 얻기 : SHQueryRecycleBin

 

이런 함수들이 있습니다.


MSDN에서 참고 하실만한 페이지에는

1. Managing the File System

    SHFileOperation 함수를 사용하는 응용예가 가장 자세히, 그리고 Notify와 Recent 연동까지.. 잘 나와있습니다.

2. Shell Functions

    일반적으로 다루는 쉘함수들의 리스트가 쭉 나와 있구요, 평소에 접하지 못하는 혹은 필요한데 못찾던것들 까지

    잘 구분되어 있습니다.


그럼 즐거운 한주 되세요...


이 글에 평점 주기:  
[코멘트]  2003-11-17 17:42:00
조갑열 (cgl777)   조갑열님께 메시지 보내기조갑열님을 내 주소록에 추가합니다.조갑열님의 개인게시판 가기 
ecycleBinDlg.cpp
F:\download\휴지통 복구\RecycleBinDlg.cpp(9) : fatal error C1083: Cannot open include file: 'ShObjIdl.h': No such file or directory
Generating Code...
Error executing cl.exe.
Creating browse info file...
BSCMAKE: error BK1506 : cannot open file '.\Debug\RecycleBinDlg.sbr': No such file or directory
Error executing bscmake.exe.

RecycleBin.exe - 2 error(s), 0 warning(s)
이 에러는 뭘까요..ㅠ.ㅠ?
 
[코멘트]  2003-11-17 19:50:00
까막 (crowback)   까막님께 메시지 보내기까막님을 내 주소록에 추가합니다.까막님의 개인게시판 가기 
ShObjIdl.h' 파일을 찾을 수 없다는 에러 메시지네요..
위의 헤더 파일을 사용하시려면 Platform SDK를 설치하셔야 합니다.
DWORD Err;

PIP_ADAPTER_INFO pAdapterInfo, pAdapt;

DWORD AdapterInfoSize = 0;

PIP_ADDR_STRING pAddrStr;



//버퍼 사이즈 알아오기

if ((Err = GetAdaptersInfo(NULL, &AdapterInfoSize)) != 0)

if (Err != ERROR_BUFFER_OVERFLOW)

return FALSE;



//버퍼 동적 할당

if ((pAdapterInfo = (PIP_ADAPTER_INFO)new BYTE[AdapterInfoSize]) == NULL)

return FALSE;



//어댑터 정보 얻어오기

if ((Err = GetAdaptersInfo(pAdapterInfo, &AdapterInfoSize)) != 0)

return FALSE;



pAdapt = pAdapterInfo;



int i=0;

while (pAdapt) -->이반복문에서 랜카드 갯수 만큼 루프를 돌면서 주소값을 얻어옵니다.

{

pAddrStr=&(pAdapt->IpAddressList);

g_sClientinternalsockaddr.bySockaddrcount=(i+1);



while(pAddrStr)

{

g_sClientinternalsockaddr.asockaddr[i].sin_addr.S_un.S_addr=inet_addr(pAddrStr->IpAddress.String);

pAddrStr = pAddrStr->Next;

}

pAdapt = pAdapt->Next;

i++;

}

delete pAdapterInfo;

pAdapterInfo=NULL;





혹은





// 로컬 어드레스를 세트한다.

char recvline[300];

gethostname(recvline, 200);



// 이름으로부터 IP를 얻어낸다.

struct hostent *pHostEnt = gethostbyname(recvline);



if (pHostEnt != NULL)

{

localAddress.Format("%u.%u.%u.%u",

0xff & pHostEnt->h_addr_list[0][0],

0xff & pHostEnt->h_addr_list[0][1],

0xff & pHostEnt->h_addr_list[0][2],

0xff & pHostEnt->h_addr_list[0][3]

);

} else

localAddress = _T("");

+ Recent posts