Thread: Windows Specific File I/O

  1. #16
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by MacGyver View Post
    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.
    Perhaps not, but what's done is done, so let's leave it at that and move on.
    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.

  2. #17
    Internet Superhero
    Join Date
    Sep 2006
    Location
    Denmark
    Posts
    964
    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.
    I was uncertain whether or not the Windows API functions used the same kind of text/binary modes as the functions from the STL, just as i wrote in my original post. Sethjackson replies that there are no difference when using the API functions, and then you quote him saying he is wrong and that the functions from the STL does indeed differ between binary and text mode, that is kind of irrelevant, is it not? Anyways, not trying to put anyone off here.

    When i've read the some of the file into my buffer the first time, will the file pointer be at the same place as the data that was last read? Or do i have to tell it in some way that i don't want it to jump to the beginning and read the same data again? Basically: Is there an equivalent of fseek?

    Edit: Nvm, i just tried it out and it seems that the file pointer stays in it's place, hence no need for an fseek equivalent
    Last edited by Neo1; 03-03-2008 at 02:11 PM.
    How I need a drink, alcoholic in nature, after the heavy lectures involving quantum mechanics.

  3. #18
    Deathray Engineer MacGyver's Avatar
    Join Date
    Mar 2007
    Posts
    3,210
    If you do end up needing to seek:

    SetFilePointer
    SetFilePointerEx

  4. #19
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by Neo1 View Post
    I was uncertain whether or not the Windows API functions used the same kind of text/binary modes as the functions from the STL, just as i wrote in my original post. Sethjackson replies that there are no difference when using the API functions, and then you quote him saying he is wrong and that the functions from the STL does indeed differ between binary and text mode, that is kind of irrelevant, is it not? Anyways, not trying to put anyone off here.
    Shrug. Let it be said, just as well...

    When i've read the some of the file into my buffer the first time, will the file pointer be at the same place as the data that was last read? Or do i have to tell it in some way that i don't want it to jump to the beginning and read the same data again? Basically: Is there an equivalent of fseek?

    Edit: Nvm, i just tried it out and it seems that the file pointer stays in it's place, hence no need for an fseek equivalent
    Yep, as you see, the file point remains in place where the last read/write stopped.
    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. #20
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    On a side note, the ReadFile documentation contains at least two errors I know of.

    1) The conditions under which it returns are incomplete. In particular, there are two conditions not listed here:
    a) End of file is reached. (NOT an error. The function returns FALSE on error.)
    b) If the operation is asynchronous, the function returns immediately.

    2) It claims the file must have been opened with GENERIC_READ access. Actually, FILE_READ_DATA suffices.

    Note: #1 is definitely a documentation bug, since the documented behaviour doesn't make sense. #2 could be simply undocumented behaviour, so don't rely on FILE_READ_DATA being sufficient. MS could later add the requirement for FILE_READ_ATTRIBUTES or FILE_READ_EA to ReadFile and your program would break. However, one quite prominent blogger claims it's a bug, so I'll go with that.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  6. #21
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Why not report it then?
    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. #22
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    I have. Several months ago. I have never heard back, nor has the documentation been fixed.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  8. #23
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Hmmm. Well, I was acknowledged when I reported the Sleep inconsistency doc bug.
    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.

  9. #24
    Internet Superhero
    Join Date
    Sep 2006
    Location
    Denmark
    Posts
    964
    Ok, so i'm almost done now

    Code:
    #include <windows.h>
    #include <iostream>
    #include <string>
    
    int main(int argc, char* argv[])
    {
    	if(argc != 3)
    	{
    		std::cerr << "Invalid number of arguments, "
    				  << "Correct usage is: split FILEPATH NUMBEROFOUTPUTFILES" << std::endl;
    		return 1;
    	}
    	
    	const unsigned int NumberOfOutputFiles = strtol(argv[2], NULL, 10);
    	
    	if(!NumberOfOutputFiles)
    	{
    		std::cerr << "Divison by 0!! BOOM the world just collapsed, try again..." << std::endl;
    		return 1;
    	}
    	
    	unsigned long OutputFileSize = 0;
    	unsigned int i = 1;
    	char *pBuffer = NULL;
    	std::string OutputFileName;
    	HANDLE hFile = CreateFile(argv[1], GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    	
    	if(!hFile)
    	{
    		std::cerr << "No such file." << std::endl;
    		return 1;
    	}
    	
    	unsigned long TotalFileSize = GetFileSize(hFile, NULL);
    	OutputFileSize = TotalFileSize / NumberOfOutputFiles;
    	pBuffer = new char[OutputFileSize];
    	
    	std::cout << "File size is: " << TotalFileSize << " bytes." << std::endl;
    	std::cout << "Splitting into " << NumberOfOutputFiles << " files - " << OutputFileSize << " bytes each." << std::endl;
    	
    	DWORD dwBytesRead, lpNumberOfBytesWritten; //Necessary to avoid Segfaults
    	HANDLE OutputHandle;
    	
    	for(; i <= NumberOfOutputFiles; i++)
    	{
    		OutputFileName = "PART" + i;
    		OutputFileName += argv[1];
    		
    		ReadFile(hFile, pBuffer, OutputFileSize, &dwBytesRead, NULL);
    		OutputHandle = CreateFile(OutputFileName.c_str(), GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    		WriteFile(OutputHandle, pBuffer, OutputFileSize, &lpNumberOfBytesWritten, NULL);
    	}
    	
    	delete[] pBuffer;
    	return 0;
    }
    (Notice how i'm not using exit() Elysia )

    It's not working correctly though. First of all, the OutputFileName that i am generating in the for loop is not quite working as expected. If i call the program like this:

    split soeasy.mp3 3
    I get 3 output files, one of them called "ARTsoeasy.mp3" another one called "RTsoeasy.mp3", and the last one is just "Tsoeasy.mp3", what is wrong?

    Also, if i tell it to split the file into 4 or 5 pieces, it still only outputs the above 3 files?
    Last edited by Neo1; 03-03-2008 at 02:54 PM. Reason: Typo
    How I need a drink, alcoholic in nature, after the heavy lectures involving quantum mechanics.

  10. #25
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by Neo1 View Post
    OutputFileName = "PART" + i;
    OutputFileName += argv[1];
    This shouldn't even compile, because it's plain wrong. Convert to string first, then add, otherwise it will probably do an implicit conversion to char and add - NOT what you want.
    Also be careful about the size of each file. You're using integer division, which means you might actually loose some bytes there. So if it's a 2 MB file, you won't get even division.
    I'd set the last output file size to (num_files - 1 * filepartsize) to make sure all bytes are copied.
    Last edited by Elysia; 03-03-2008 at 03:02 PM.
    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. #26
    Internet Superhero
    Join Date
    Sep 2006
    Location
    Denmark
    Posts
    964
    Quote Originally Posted by Elysia View Post
    This shouldn't even compile, because it's plain wrong. Convert to string first, then add, otherwise it will probably do an implicit conversion to char and add - NOT what you want.
    Convert what to a string first? OutputFileName is already a std::string, i'm guessing it's the "+ i" that is wrong?

    And why shouldn't it compile, G++ has nothing to say about it with -Wall -ansi -pedantic?
    How I need a drink, alcoholic in nature, after the heavy lectures involving quantum mechanics.

  12. #27
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    You can't add an integer to the string directly.
    Code:
    	int n = 1000000;
    	OutputFileName += n;
    I get a warning about an implicit conversion from int to char.
    So what it does is convert your integer into a char and call operator += (char), which is bad.
    So you need to convert that integer into a string first. Probably via stringstreams.

    The
    OutputFileName = "PART" + i; (+ i)
    is bad because the result won't be what you expect.
    I'm not sure what happens, but if you add i afterwards, you get an implicit conversion to a char.
    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.

  13. #28
    Internet Superhero
    Join Date
    Sep 2006
    Location
    Denmark
    Posts
    964
    Quote Originally Posted by Elysia View Post
    You can't add an integer to the string directly.
    Code:
    	int n = 1000000;
    	OutputFileName += n;
    I get a warning about an implicit conversion from int to char.
    So what it does is convert your integer into a char and call operator += (char), which is bad.
    So you need to convert that integer into a string first. Probably via stringstreams.
    Strange, i get no warnings, anyways, i'll fix it then

    Also, could you elaborate abit on the integer division thing. I'm aware that division with an integer will result in some inaccuracy, but if i were to rewrite the last WriteFile call from

    Code:
    WriteFile(OutputHandle, pBuffer, OutputFileSize, &lpNumberOfBytesWritten, NULL);
    to

    Code:
    WriteFile(OutputHandle, pBuffer, (NumberOfOutputFiles - 1 * OutputFileSize), &lpNumberOfBytesWritten, NULL);
    I'd also have to increase the size of my buffer right?

    Code:
    OutputFileSize = TotalFileSize / NumberOfOutputFiles;
    	pBuffer = new char[NumberOfOutputFiles - 1 * OutputFileSize];
    Is this correct?
    How I need a drink, alcoholic in nature, after the heavy lectures involving quantum mechanics.

  14. #29
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by Neo1 View Post
    Strange, i get no warnings, anyways, i'll fix it then
    Well, it's because gcc does not have any narrowing warnings, unlike Visual Studio.

    Also, could you elaborate abit on the integer division thing. I'm aware that division with an integer will result in some inaccuracy, but if i were to rewrite the last WriteFile call from

    Code:
    WriteFile(OutputHandle, pBuffer, OutputFileSize, &lpNumberOfBytesWritten, NULL);
    to

    Code:
    WriteFile(OutputHandle, pBuffer, (NumberOfOutputFiles - 1 * OutputFileSize), &lpNumberOfBytesWritten, NULL);
    I'd also have to increase the size of my buffer right?

    Code:
    OutputFileSize = TotalFileSize / NumberOfOutputFiles;
    	pBuffer = new char[NumberOfOutputFiles - 1 * OutputFileSize];
    Is this correct?
    You would indeed have to increase the buffer... I think that looks about right.
    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. #30
    Internet Superhero
    Join Date
    Sep 2006
    Location
    Denmark
    Posts
    964
    So this is how the code looks now:

    Code:
    #include <windows.h>
    #include <iostream>
    #include <string>
    #include <sstream>
    
    int main(int argc, char* argv[])
    {
    	if(argc != 3)
    	{
    		std::cerr << "Invalid number of arguments, "
    				  << "Correct usage is: split FILEPATH NUMBEROFOUTPUTFILES" << std::endl;
    		return 1;
    	}
    	
    	const unsigned int NumberOfOutputFiles = strtol(argv[2], NULL, 10);
    	
    	if(!NumberOfOutputFiles)
    	{
    		std::cerr << "Divison by 0!! BOOM the world just collapsed, try again..." << std::endl;
    		return 1;
    	}
    	
    	unsigned long OutputFileSize = 0;
    	unsigned int i = 1;
    	char *pBuffer = NULL;
    	std::string OutputFileName;
    	HANDLE hFile = CreateFile(argv[1], GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    	
    	if(!hFile)
    	{
    		std::cerr << "No such file." << std::endl;
    		return 1;
    	}
    	
    	unsigned long TotalFileSize = GetFileSize(hFile, NULL);
    	OutputFileSize = TotalFileSize / NumberOfOutputFiles;
    	pBuffer = new char[NumberOfOutputFiles - 1 * OutputFileSize];
    	
    	std::cout << "File size is: " << TotalFileSize << " bytes." << std::endl;
    	std::cout << "Splitting into " << NumberOfOutputFiles << " files - " << OutputFileSize << " bytes each." << std::endl;
    	
    	DWORD dwBytesRead, lpNumberOfBytesWritten; //Necessary to avoid Segfaults
    	HANDLE OutputHandle;
    	
    	std::stringstream ss (std::stringstream::in | std::stringstream::out); // Used for converting 'i' to a std::string
    	
    	
    	for(; i <= NumberOfOutputFiles; i++)
    	{
    		ss << "PART" << i << argv[1];
    		OutputFileName = ss.str();
    		
    		ReadFile(hFile, pBuffer, OutputFileSize, &dwBytesRead, NULL);
    		OutputHandle = CreateFile(OutputFileName.c_str(), GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    		if(i == NumberOfOutputFiles)
    			WriteFile(OutputHandle, pBuffer, (NumberOfOutputFiles - 1 * OutputFileSize), &lpNumberOfBytesWritten, NULL);
    		
    		else
    			WriteFile(OutputHandle, pBuffer, OutputFileSize, &lpNumberOfBytesWritten, NULL);
    	}
    	
    	delete[] pBuffer;
    	return 0;
    }
    It compiles with no warnings or errors, but whenever i run it i just get a message saying:
    This application has requested the Runtime to terminate it in an unusual way.
    Please contact the application's support team for more information.
    The thing is though, i haven't yet gotten around to creating a support team yet :P
    Any idea what is wrong?
    How I need a drink, alcoholic in nature, after the heavy lectures involving quantum mechanics.

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