-
Win32Platform/File(장치 IO) 2009. 1. 22. 17:57CreateFile()
INVALID_HANDLE_VALUE
dwDesiredAccessGENERIC_READ
GENERIC_WRITE
dwShareModeFILE_SHARE_READ
dwCreationDisposition
OPEN_EXISTING
CREATE_ALWAYS
dwFlagsAndAttributesFILE_ATTRIBUTE_NORMAL
FILE_ATTRIBUTE_ARCHIVE
FILE_ATTRIBUTE_READONLY
FILE_FLAG_OVERLAPPED
c.f. OpenFile() - compatibility
CloseHandle()
WriteFile()
WriteFileEx()
ReadFile()
ReadFileEx()
GetOverlappedResult()
SetFilePointer()
FILE_BEGINFILE_CURRENT
LARGE_INTEGER CurPtr;
DWORD FPos;
CurPtr.QuadPart = (LONGLONG)..;
FPos = SetFilePointer(hInFile, CurPtr.LowPart, &CurPtr.HighPart, FILE_BEGIN);
if (FPos == 0xFFFFFFFF && GetLastError() != NO_ERROR) ReportError(_T(".."));GetFileSize()
SetEndOfFile()
SetFileValidData()
DeviceIoControl()
LockFileEx()
UnlockFileEx()
LockFile()
UnlockFile()
BOOL Save()
{
if (lstrcmp(NowFile,"제목없음.txt")==0) {
return SaveAs();
} else {
return SaveToFile(NowFile);
}
}
BOOL SaveAs()
{
OPENFILENAME OFN;
TCHAR lpstrFile[MAX_PATH]="";
memset(&OFN, 0, sizeof(OPENFILENAME));
OFN.lStructSize = sizeof(OPENFILENAME);
OFN.hwndOwner=hWndMain;
OFN.lpstrFilter="Text File\0*.txt;*.doc\0Every File(*.*)\0*.*\0";
OFN.lpstrFile=lpstrFile;
OFN.nMaxFile=MAX_PATH;
OFN.lpstrDefExt="txt";
if (GetSaveFileName(&OFN)==FALSE) {
return FALSE;
}
return SaveToFile(NowFile);
}
BOOL SaveToFile(TCHAR *Path)
{
HANDLE hFile;
DWORD dwWritten;
hFile=CreateFile(Path,GENERIC_WRITE,0,NULL,
CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
if (hFile==INVALID_HANDLE_VALUE) {
return FALSE;
}
WriteFile(hFile,buf,length,&dwWritten,NULL);
CloseHandle(hFile);
return TRUE;
}
void Open()
{
OPENFILENAME OFN;
TCHAR lpstrFile[MAX_PATH]="";
HANDLE hFile;
DWORD dwRead;
DWORD size;
TCHAR *buf;
if (ConfirmSave() == IDCANCEL) {
return;
}
memset(&OFN, 0, sizeof(OPENFILENAME));
OFN.lStructSize = sizeof(OPENFILENAME);
OFN.hwndOwner=hWndMain;
OFN.lpstrFilter="Text File\0*.txt;*.doc\0Every File(*.*)\0*.*\0";
OFN.lpstrFile=lpstrFile;
OFN.nMaxFile=MAX_PATH;
OFN.lpstrDefExt="txt";
if (GetOpenFileName(&OFN)==FALSE) {
return;
}
hFile=CreateFile(OFN.lpstrFile,GENERIC_READ,0,NULL,
OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
if (hFile==INVALID_HANDLE_VALUE) {
MessageBox(hWndMain,"파일을 열 수 없습니다.","에러",MB_OK);
return;
}
size=GetFileSize(hFile,NULL);
buf=(TCHAR *)calloc(size+1,1);
ReadFile(hFile,buf,size,&dwRead,NULL);
CloseHandle(hFile);
...
free(buf);
}
int ConfirmSave()
{
int result=IDNO;
TCHAR Mes[MAX_PATH+64];
if (...==TRUE) {
wsprintf(Mes,"%s 파일이 변경되었습니다. 저장하시겠습니까?",NowFile);
result=MessageBox(hWndMain,Mes,"알림",MB_YESNOCANCEL);
if (result == IDCANCEL) {
return IDCANCEL;
}
if (result == IDYES) {
if (Save() == FALSE)
return IDCANCEL;
else
return IDYES;
}
}
return result;
}
#include <windows.h>
#include <stdio.h>
#define BUF_SIZE 256
int main (int argc, LPTSTR argv [])
{
HANDLE hIn, hOut;
DWORD nIn, nOut;
CHAR Buffer [BUF_SIZE];
// BYTE pBuffer[1024]; // Read from file in 1K chunks
if (argc != 3) {
printf ("Usage: cp file1 file2\n");
return 1;
}
hIn = CreateFile (argv [1], GENERIC_READ, FILE_SHARE_READ, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hIn == INVALID_HANDLE_VALUE) {
printf ("Cannot open input file. Error: %x\n", GetLastError ());
return 2;
}
hOut = CreateFile (argv [2], GENERIC_WRITE, 0, NULL,
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hOut == INVALID_HANDLE_VALUE) {
printf ("Cannot open output file. Error: %x\n", GetLastError ());
return 3;
}
while (ReadFile (hIn, Buffer, BUF_SIZE, &nIn, NULL) && nIn > 0) {
// while (ReadFile (hIn, Buffer, sizeof(Buffer), &nIn, NULL) && nIn > 0) {
WriteFile (hOut, Buffer, nIn, &nOut, NULL);
if (nIn != nOut) {
printf ("Fatal write error: %x\n", GetLastError ());
return 4;
}
}
CloseHandle (hIn);
CloseHandle (hOut);
return 0;
}#include <windows.h>
#include <stdio.h>
int main (int argc, LPTSTR argv [])
{
if (argc != 3) {
printf ("Usage: cp file1 file2\n");
return 1;
}
if (!CopyFile (argv [1], argv [2], FALSE)) {
printf ("CopyFile Error: %x\n", GetLastError ());
return 2;
}
return 0;
}
/* RecordAccess. */
#include <WINIOCTL.H>
#define STRING_SIZE 256
typedef struct _RECORD { /* File record structure */
DWORD ReferenceCount; /* 0 meands an empty record */
SYSTEMTIME RecordCreationTime;
SYSTEMTIME RecordLastRefernceTime;
SYSTEMTIME RecordUpdateTime;
TCHAR DataString[STRING_SIZE];
} RECORD;
typedef struct _HEADER { /* File header descriptor */
DWORD NumRecords;
DWORD NumNonEmptyRecords;
} HEADER;
int _tmain (int argc, LPTSTR argv [])
{
HANDLE hFile;
LARGE_INTEGER CurPtr;
DWORD FPos, OpenOption, nXfer, RecNo, FsFlags;
RECORD Record;
TCHAR String[STRING_SIZE], Command, Extra;
OVERLAPPED ov = {0, 0, 0, 0, NULL}, ovZero = {0, 0, 0, 0, NULL};
HEADER Header = {0, 0};
SYSTEMTIME CurrentTime;
BOOLEAN HeaderChange, RecordChange;
if (argc < 2)
ReportError (_T ("Usage: RecordAccess file [nrec]"), 1, FALSE);
OpenOption = (argc == 2) ? OPEN_EXISTING : CREATE_ALWAYS;
hFile = CreateFile (argv [1], GENERIC_READ | GENERIC_WRITE,
0, NULL, OpenOption, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE)
ReportError (_T ("RecordAccess error: Cannot open existing file."), 2, TRUE);
if (argc >= 3) { /* Write the header (all header and pre-size the new file) */
#if 0
/* First, make the file sparse if possible - Recommended for large files */
/* Challenge - get this to work properly - alternatively, make it sparse */
/* adminstratively. This code, taken from several MS examples, fails on XP Home. */
if (!GetVolumeInformation (_T("C:\\"), NULL, 0, NULL, NULL, &FsFlags , NULL, 0))
ReportError (_T("RecordAccess Error: GetVolumeInformation."), 3, TRUE);
if (FsFlags & FILE_SUPPORTS_SPARSE_FILES) {
if ((FsFlags & FILE_SUPPORTS_SPARSE_FILES) &&
!DeviceIoControl (hFile, FSCTL_SET_SPARSE, NULL, 0, NULL, 0, &nXfer, NULL))
ReportError (_T("RecordAccess Error: Making new file sparse."), 0, TRUE);
}
_tprintf (_T("Is it sparse? %x\n"),
GetFileAttributes(argv[1]) & FILE_ATTRIBUTE_SPARSE_FILE);
#endif
Header.NumRecords = atoi(argv[2]);
if (!WriteFile(hFile, &Header, sizeof (Header), &nXfer, &ovZero))
ReportError (_T ("RecordAccess Error: WriteFile header."), 4, TRUE);
CurPtr.QuadPart = sizeof(RECORD) * atoi(argv[2]) + sizeof(HEADER);
FPos = SetFilePointer (hFile, CurPtr.LowPart, &CurPtr.HighPart, FILE_BEGIN);
if (FPos == 0xFFFFFFFF && GetLastError () != NO_ERROR)
ReportError (_T ("RecordAccess Error: Set Pointer."), 4, TRUE);
if (!SetEndOfFile(hFile))
ReportError (_T ("RecordAccess Error: Set End of File."), 5, TRUE);
}
/* Read the file header to find the number of records and non-empty records */
if (!ReadFile(hFile, &Header, sizeof (HEADER), &nXfer, &ovZero))
ReportError (_T ("RecordAccess Error: ReadFile header."), 6, TRUE);
_tprintf (_T("File %s contains %d non-empty records of size %d. Total capacity is: %d\n"),
argv[1], Header.NumNonEmptyRecords, sizeof(RECORD), Header.NumRecords);
/* Prompt the user to read or write a numbered record */
while (TRUE) {
HeaderChange = FALSE; RecordChange = FALSE;
_tprintf (_T("Enter r(ead)/w(rite)/d(elete)/q(uit) Record#\n"));
_tscanf (_T ("%c" "%d" "%c"), &Command, &RecNo, &Extra );
if (Command == 'q') break;
if (RecNo >= Header.NumRecords) {
_tprintf (_T("Record Number is too large. Try again.\n"));
continue;
}
CurPtr.QuadPart = RecNo * sizeof(RECORD) + sizeof(HEADER);
ov.Offset = CurPtr.LowPart;
ov.OffsetHigh = CurPtr.HighPart;
if (!ReadFile (hFile, &Record, sizeof (RECORD), &nXfer, &ov))
ReportError (_T ("RecordAccess: ReadFile failure."), 7, FALSE);
GetSystemTime (&CurrentTime); /* Use to update record time fields */
Record.RecordLastRefernceTime = CurrentTime;
if (Command == 'r' || Command == 'd') { /* Report record contents, if any */
if (Record.ReferenceCount == 0) {
_tprintf (_T("Record Number %d is empty.\n"), RecNo);
continue;
} else {
_tprintf (_T("Record Number %d. Reference Count: %d \n"),
RecNo, Record.ReferenceCount);
_tprintf (_T("Data: %s\n"), Record.DataString);
/* Exercise: Display times. See ls.c for an example */
RecordChange = TRUE;
}
if (Command == 'd') { /* Delete the record */
/* Challenge: In a sparse file, implement this with the
FSCTL_SET_ZERO_DATA flag on DeviceIoControl() */
_tprintf (_T("About to delete this record.\n"));
Record.ReferenceCount = 0;
Header.NumNonEmptyRecords--;
HeaderChange = TRUE;
RecordChange = TRUE;
}
} else if (Command == 'w') { /* Write the record, even if for the first time */
_tprintf (_T("Enter new data string for the record.\n"));
_getts (String);
if (Record.ReferenceCount == 0) {
Record.RecordCreationTime = CurrentTime;
Header.NumNonEmptyRecords++;
HeaderChange = TRUE;
}
Record.RecordUpdateTime = CurrentTime;
Record.ReferenceCount++;
_tcsncpy (Record.DataString, String, STRING_SIZE-1);
RecordChange = TRUE;
} else {
_tprintf (_T("Command must be r, w, or d. Try again.\n"));
}
/* Update the record in place if any record contents have changed. */
if (RecordChange && !WriteFile (hFile, &Record, sizeof (RECORD), &nXfer, &ov))
ReportError (_T ("RecordAccess: WriteFile update failure."), 8, FALSE);
/* Update the number of non-empty records if required */
if (HeaderChange) {
if (!WriteFile (hFile, &Header, sizeof (Header), &nXfer, &ovZero))
ReportError (_T ("RecordAccess: WriteFile update failure."), 9, FALSE);
}
}
_tprintf (_T("Computed number of non-empty records is: %d\n"), Header.NumNonEmptyRecords);
if (!ReadFile(hFile, &Header, sizeof (HEADER), &nXfer, &ovZero))
ReportError (_T ("RecordAccess Error: ReadFile header."), 10, TRUE);
_tprintf (_T("File %s NOW contains %d non-empty records. Total capacity is: %d\n"),
argv[1], Header.NumNonEmptyRecords, Header.NumRecords);
CloseHandle (hFile);
return 0;
}/* tail */
#define NUM_LINES 11
/* One more than number of lines in the tail. */
#define MAX_LINE_SIZE 256
#define MAX_CHAR NUM_LINES*MAX_LINE_SIZE
int _tmain (int argc, LPTSTR argv [])
{
HANDLE hInFile;
HANDLE hStdOut = GetStdHandle (STD_OUTPUT_HANDLE);
LARGE_INTEGER FileSize, CurPtr;
LARGE_INTEGER LinePos [NUM_LINES];
DWORD LastLine, FirstLine, LineCount, nRead, FPos;
TCHAR Buffer [MAX_CHAR + 1], c;
if (argc != 2)
ReportError (_T ("Usage: tail file"), 1, FALSE);
hInFile = CreateFile (argv [1], GENERIC_READ,
0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hInFile == INVALID_HANDLE_VALUE)
ReportError (_T ("tail error: Cannot openfile."), 2, TRUE);
/* Get the current file size. */
FileSize.LowPart = GetFileSize (hInFile, &FileSize.HighPart);
if (FileSize.LowPart == 0xFFFFFFFF && GetLastError () != NO_ERROR)
ReportError (_T ("tail error: file size"), 3, TRUE);
/* Set the file pointer on the assumption that 256
is the maximum size and look for the line beginnings.
If 10 lines are not located, then just put out the
ones that are found. A more general solution would look
farther back in the file if necessary. Alternatively,
start the scan at the beginning of the file, but that
would be time consuming for a large file. */
CurPtr.QuadPart = (LONGLONG)FileSize.QuadPart
- NUM_LINES * MAX_LINE_SIZE * sizeof (TCHAR);
if (CurPtr.QuadPart < 0) CurPtr.QuadPart = 0;
FPos = SetFilePointer (hInFile, CurPtr.LowPart, &CurPtr.HighPart, FILE_BEGIN);
if (FPos == 0xFFFFFFFF && GetLastError () != NO_ERROR)
ReportError (_T ("tail Error: Set Pointer."), 4, TRUE);
/* Scan the file for the start of new lines and retain their
position. Assume that a line starts at the current position. */
LinePos [0].QuadPart = CurPtr.QuadPart;
LineCount = 1;
LastLine = 1;
while (TRUE) {
while (ReadFile (hInFile, &c, sizeof (TCHAR), &nRead, NULL)
&& nRead > 0 && c != CR) ; /* Empty loop body */
if (nRead < sizeof (TCHAR)) break;
/* Found a CR. Is LF next? */
ReadFile (hInFile, &c, sizeof (TCHAR), &nRead, NULL);
if (nRead < sizeof (TCHAR)) break;
if (c != LF) continue;
CurPtr.QuadPart = 0;
/* Get the current file position. */
CurPtr.LowPart = SetFilePointer (
hInFile, 0, &CurPtr.HighPart, FILE_CURRENT);
/* Retain the start-of-line position */
LinePos [LastLine].QuadPart = CurPtr.QuadPart;
LineCount++;
LastLine = LineCount % NUM_LINES;
}
FirstLine = LastLine % NUM_LINES;
if (LineCount < NUM_LINES) FirstLine = 0;
CurPtr.QuadPart = LinePos [FirstLine].QuadPart;
/* The start of each line is now stored in LinePos []
with the last line having index LastLine.
Display the last strings. */
SetFilePointer (hInFile, CurPtr.LowPart, &CurPtr.HighPart, FILE_BEGIN);
ReadFile (hInFile, Buffer, sizeof (Buffer), &nRead, NULL);
Buffer [nRead] = '\0';
PrintMsg (hStdOut, Buffer);
CloseHandle (hInFile);
return 0;
}
참조 사이트: