Thread: Windows Specific File I/O

  1. #1
    Internet Superhero
    Join Date
    Sep 2006
    Location
    Denmark
    Posts
    964

    Windows Specific File I/O

    I'm trying to make a small application that will read in a file, split it up and output each part to a different file. I'm trying to do this using Windows specific file I/O, and basically i'm completely lost. This is what i have so far:

    Code:
    #include <windows.h>
    #include <iostream>
    
    int main(int argc, char* argv[])
    {
            const CHAR *file = "soeasy.mp3"; //This is hardcoded for now, ill change that when the rest works.
    
            HANDLE hfile = CreateFile(file, 
    						GENERIC_READ, 
    						0, 
    						NULL, 
    						OPEN_EXISTING, 
    						FILE_ATTRIBUTE_NORMAL, 
    						NULL);
    
    	unsigned long file_length = GetFileSize(hfile, NULL);
    	
    	std::cout << file_length << std::endl;
    	return 0;
    }
    In explorer the file "soeasy.mp3" is 3,66 MB. But the output i am getting is 3841925, is there something wrong with the code? And why doesn't the sizes match up?

    After i've gotten the file size, i've got to allocate enough memory to read the filesize divided by the number of output files into memory, i'm guessing i have to use ReadFile() for this? Is there a difference between binary I/O and text file I/O with theese functions, like with fstream?

    When should i call GetLastError()? After each of the function calls or? Anything else that i am forgetting?
    How I need a drink, alcoholic in nature, after the heavy lectures involving quantum mechanics.

  2. #2
    Deathray Engineer MacGyver's Avatar
    Join Date
    Mar 2007
    Posts
    3,210
    3841925 bytes / 1024 = 3751.8798828125 KB
    3751.8798828125 KB / 1024 = 3.66394519805908203125 MB

    That seems about right. What are you expecting?

  3. #3
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    According to "calc":
    3841925 / (1024 * 1024) becomes 3.66394519805908203125

    So I guess Explorer is just rounding, and not very far off.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  4. #4
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by Neo1 View Post
    In explorer the file "soeasy.mp3" is 3,66 MB. But the output i am getting is 3841925, is there something wrong with the code? And why doesn't the sizes match up?
    3.66 x 1024 x 1024 = 3837788.16, so I wouldn't say you're completely off track.
    Plus I don't know if it returns the actual size on disk or the actual file size.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  5. #5
    Registered User
    Join Date
    Aug 2005
    Posts
    96
    Quote Originally Posted by Neo1 View Post
    I'm trying to make a small application that will read in a file, split it up and output each part to a different file. I'm trying to do this using Windows specific file I/O, and basically i'm completely lost. This is what i have so far:

    Code:
    #include <windows.h>
    #include <iostream>
    
    int main(int argc, char* argv[])
    {
            const CHAR *file = "soeasy.mp3"; //This is hardcoded for now, ill change that when the rest works.
    
            HANDLE hfile = CreateFile(file, 
    						GENERIC_READ, 
    						0, 
    						NULL, 
    						OPEN_EXISTING, 
    						FILE_ATTRIBUTE_NORMAL, 
    						NULL);
    
    	unsigned long file_length = GetFileSize(hfile, NULL);
    	
    	std::cout << file_length << std::endl;
    	return 0;
    }
    In explorer the file "soeasy.mp3" is 3,66 MB. But the output i am getting is 3841925, is there something wrong with the code? And why doesn't the sizes match up?

    After i've gotten the file size, i've got to allocate enough memory to read the filesize divided by the number of output files into memory, i'm guessing i have to use ReadFile() for this? Is there a difference between binary I/O and text file I/O with theese functions, like with fstream?

    When should i call GetLastError()? After each of the function calls or? Anything else that i am forgetting?
    To read data, you use ReadFile(). AFAIK there is no difference between binary/text with ReadFile(). You are just reading bytes.

    MSDN recommends that you use GetFileSizeEx() instead of GetFileSize().
    I have used GetFileSizeEx() and it correctly reports the number of bytes in the file.

    EDIT:

    Heh see above too.

  6. #6
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by sethjackson View Post
    To read data, you use ReadFile(). AFAIK there is no difference between binary/text with ReadFile(). You are just reading bytes.
    No, that's not true. In text mode, newlines are translated into '\n', and bytes that represent the value of "end of file" are also picked up, thus prematurely setting EOF for a file. To read text files, use text mode; other files, use binary. This only applies to C/C++, however.
    OpenFile/ReadFile does not have text/binary mode AFAIK.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  7. #7
    Deathray Engineer MacGyver's Avatar
    Join Date
    Mar 2007
    Posts
    3,210
    Quote Originally Posted by Elysia View Post
    No, that's not true. In text mode, newlines are translated into '\n', and bytes that represent the value of "end of file" are also picked up, thus prematurely setting EOF for a file. To read text files, use text mode; other files, use binary. This only applies to C/C++, however.
    OpenFile/ReadFile does not have text/binary mode AFAIK.
    Isn't that what he said?

  8. #8
    Internet Superhero
    Join Date
    Sep 2006
    Location
    Denmark
    Posts
    964
    Quote Originally Posted by MacGyver View Post
    3841925 bytes / 1024 = 3751.8798828125 KB
    3751.8798828125 KB / 1024 = 3.66394519805908203125 MB

    That seems about right. What are you expecting?
    Silly me, i was dividing by 1000 not 1024, so i guess the first part is fine. This is how it looks right now:

    Code:
    #include <windows.h>
    #include <iostream>
    
    int main(int argc, char* argv[])
    {
    	const unsigned int NumberOfOutputFiles = 3;
    	unsigned long OutputFileSize = 0;
    	const CHAR *File = "soeasy.mp3";
    	char *pBuffer = NULL;
    	HANDLE hFile = CreateFile(File, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    	
    	unsigned long TotalFileSize = GetFileSize(hFile, NULL);
    	
    	std::cout << "File size is: " << TotalFileSize << " bytes." << std::endl;
    	
    	OutputFileSize = TotalFileSize / NumberOfOutputFiles;
    	pBuffer = new char[OutputFileSize];
    	
    	ReadFile(hFile, pBuffer, OutputFileSize, NULL, NULL);
    	
    	delete[] pBuffer;
    	
    	return 0;
    }
    This is giving me segfaults, how come? I can't locate any obvious memory leaks or anything in there?
    How I need a drink, alcoholic in nature, after the heavy lectures involving quantum mechanics.

  9. #9
    Registered User
    Join Date
    Aug 2005
    Posts
    96
    Quote Originally Posted by Elysia View Post
    No, that's not true. In text mode, newlines are translated into '\n', and bytes that represent the value of "end of file" are also picked up, thus prematurely setting EOF for a file. To read text files, use text mode; other files, use binary. This only applies to C/C++, however.
    OpenFile/ReadFile does not have text/binary mode AFAIK.

    Which is what I said no?

  10. #10
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by MacGyver View Post
    Isn't that what he said?
    Depends on how you see, I guess.
    For Win32 there is no text/binary, so it makes no sense.
    Then one could apply it to C/C++ where it does matter.
    Just clearing it up I guess. Valuable information.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  11. #11
    Registered User
    Join Date
    Aug 2005
    Posts
    96
    From MSDN:

    http://msdn2.microsoft.com/en-us/lib...67(VS.85).aspx

    "If lpOverlapped is NULL, lpNumberOfBytesRead cannot be NULL."

    Code:
    DWORD dwBytesRead;
        
    ReadFile(hFile, pBuffer, OutputFileSize, &dwBytesRead, NULL);

  12. #12
    Registered User
    Join Date
    Aug 2005
    Posts
    96
    Quote Originally Posted by Elysia View Post
    Depends on how you see, I guess.
    For Win32 there is no text/binary, so it makes no sense.
    Then one could apply it to C/C++ where it does matter.
    Just clearing it up I guess. Valuable information.
    True. Sorry for the confusion....

  13. #13
    Internet Superhero
    Join Date
    Sep 2006
    Location
    Denmark
    Posts
    964
    Quote Originally Posted by sethjackson View Post
    From MSDN:

    http://msdn2.microsoft.com/en-us/lib...67(VS.85).aspx

    "If lpOverlapped is NULL, lpNumberOfBytesRead cannot be NULL."

    Code:
    DWORD dwBytesRead;
        
    ReadFile(hFile, pBuffer, OutputFileSize, &dwBytesRead, NULL);
    This fixed the segfaults

    True. Sorry for the confusion....
    Why do you apologize, Elysia was the one that brought up standard C++, which has got nothing to do with anything in this thread really.
    How I need a drink, alcoholic in nature, after the heavy lectures involving quantum mechanics.

  14. #14
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by Neo1 View Post
    Why do you apologize, Elysia was the one that brought up standard C++, which has got nothing to do with anything in this thread really.
    You are using C++, are you not? Then how does it have nothing to do with this thread?
    I think you are the one who was confused at first, thinking about using binary or text.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  15. #15
    Deathray Engineer MacGyver's Avatar
    Join Date
    Mar 2007
    Posts
    3,210
    One word of warning when dealing with HANDLEs. Apparently some functions that return a HANDLE return NULL to signify an invalid HANDLE, while some return INVALID_HANDLE_VALUE to signify the same thing. It's always important to always be sure to read the API documentation specifically and check to make sure you have a valid HANDLE returned from whatever specific function you use.

    And on a side note, I don't think there was any any confusion in what Seth said, hence no need for an apology from him.

    Quote Originally Posted by Elysia View Post
    You are using C++, are you not? Then how does it have nothing to do with this thread?
    I think you are the one who was confused at first, thinking about using binary or text.
    He's using the Windows API for I/O, not C++'s standard I/O. He simply wanted to know if the Windows API was the same as C++'s fstream. I think that indicates he has an idea how that works.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Newbie homework help
    By fossage in forum C Programming
    Replies: 3
    Last Post: 04-30-2009, 04:27 PM
  2. gcc link external library
    By spank in forum C Programming
    Replies: 6
    Last Post: 08-08-2007, 03:44 PM
  3. Dikumud
    By maxorator in forum C++ Programming
    Replies: 1
    Last Post: 10-01-2005, 06:39 AM
  4. Batch file programming
    By year2038bug in forum Tech Board
    Replies: 10
    Last Post: 09-05-2005, 03:30 PM
  5. simulate Grep command in Unix using C
    By laxmi in forum C Programming
    Replies: 6
    Last Post: 05-10-2002, 04:10 PM