I work quite a lot with file reading and writing in C/Win32 and I started wondering if my code is completely ugly and how I can improve it. I wrote two simple examples of reading a file, and I wonder how these functions could be improved. Are these methods bad - and how they can be improved? I use MSVC so the code might contain MS-specific macros or keywords.
BOOL read_file(PCHAR filename, PBYTE *outdata, DWORD *outsize)
{
DWORD check = 0;
BOOL success = FALSE;
HANDLE hFile = CreateFileA(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if(hFile != INVALID_HANDLE_VALUE)
{
if((*outsize = GetFileSize(hFile, NULL)) != INVALID_FILE_SIZE)
{
if((*outdata = malloc(*outsize)) != NULL)
{
if(ReadFile(hFile, *outdata, *outsize, &check, NULL) && check == *outsize)
{
success = TRUE;
}
}
}
}
if(hFile != INVALID_HANDLE_VALUE)
{
CloseHandle(hFile);
}
return success;
}
BOOL read_file2(PCHAR filename, PBYTE *outdata, DWORD *outsize)
{
DWORD check = 0;
BOOL success = TRUE;
HANDLE hFile = CreateFileA(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if(hFile == INVALID_HANDLE_VALUE)
{
success = FALSE; goto _end;
}
if((*outsize = GetFileSize(hFile, NULL)) == INVALID_FILE_SIZE)
{
success = FALSE; goto _end;
}
if((*outdata = malloc(*outsize)) == NULL)
{
success = FALSE; goto _end;
}
if(!ReadFile(hFile, *outdata, *outsize, &check, NULL) || check != *outsize)
{
success = FALSE; goto _end;
}
_end:
if(hFile != INVALID_HANDLE_VALUE)
{
CloseHandle(hFile);
}
return success;
}
Questions:
- Which one is better, and why?
- What is bad about the above examples?
- Can you show a better example or how you would do it?