-
Downloading files
My goal here is to download a file. And the theory is that if I read a Url and save it to a file, then technically that file was downloaded.
Code:
#include <stdio.h>
#include <windows.h>
#include <wininet.h>
#pragma comment (lib, "wininet.lib")
int main()
{
HINTERNET hOpen, hURL;
hOpen = InternetOpen("WebReader", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0 );
hURL = InternetOpenUrl( hOpen, "http://www.google.com",
NULL, 0, 0, 0 );
const int numRead = 99;
char file[numRead];
unsigned long read;
do
{
InternetReadFile(hURL, file, numRead, &read);
file[read] = '\0';
printf("%s", file);;
} while (read == numRead);
printf ("\n");
return 0;
}
This program works fine, the problem is that when I try to save it to a file, it doesn't work, and I get bugs within the program, and a few warnings.
Code:
#include <stdio.h>
#include <windows.h>
#include <wininet.h>
#pragma comment (lib, "wininet.lib")
int main()
{
FILE *fp; /* Added */
HINTERNET hOpen, hURL;
hOpen = InternetOpen("WebReader", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0 );
hURL = InternetOpenUrl( hOpen, "http://www.google.com",
NULL, 0, 0, 0 );
const int numRead = 99;
char file[numRead];
unsigned long read;
fp = fopen("c:\windows\desktop\whatever.txt", "w"); /* Added */
do
{
InternetReadFile(hURL, file, numRead, &read);
file[read] = '\0';
printf("%s", file);;
} while (read == numRead);
fclose(fp); /* Added */
printf ("\n");
return 0;
}
And with this code, for some reason the file doesn't open and it doesn't write the data to it. My goal is so that I can download more than just a text file. Say I would want a zip file, then I would use fopen to open a zip file and just write to it, and hopefully it will work like a zip file. I believe I am missing something really simple here, I would appreciate any help that point out my mistake.
Thank you!
-
Code:
fp = fopen("c:\windows\desktop\whatever.txt", "w");
1. For binary files, we need to use "wb". The "b" is for binary, without this the file will be opened in text mode.
2. Is that path valid? To start with you may just want to use a file in the current directory: "test.txt".
3. To embed a backslash in a string literal you must use two backslashes: "C:\\windows". A single backslash is interpreted as starting an escape sequence, such as "\n" for newline.
Code:
do
{
InternetReadFile(hURL, file, numRead, &read);
file[read] = '\0';
printf("%s", file);;
} while (read == numRead);
1. You aren't writing to the file in this loop.
2. We need to leave room for the nul character you add after the call to InternetReadFile.
Try this:
Code:
do
{
InternetReadFile(hURL, file, numRead - 1, &read);
fwrite(file, sizeof(char), read, fp);
file[read] = '\0';
printf("%s", file);
} while (read == numRead - 1);
-
You also need to clean the HINTERNETs with the InternetCloseHandle function.
-
Oh, now I see, thank you very much, I really appreciate it. I am only a beginner.
-
Oh, also one more thing, if I wanted to download a file that wasn't in text, it won't work. I believe this is because the internetOpenUrl functions are already in html text mode. But if I am writing exes or zips in binary mode, how can I make it so the functions read the file in binary mode. Becuse in the HTML text mode, it stops writing after it sees the first EOF character, so it always stops early. How can I fix this problem.
-
Just always open in binary mode. There's no reason to open in text here. (Especially when you consider that in most (all?) unix/linux variants there is no difference between the two methods. They're identical.
Quzah.
-
How do you open in binary mode? Or in this case, how can I make internetReadFile read in binary mode? Is there another function similar to internetReadFile that reads characters in binary mode? When I opened the file for writing in binary mode, it started printing, but then it stopped. When I looked at the resulting file, it showed that only about one quarter of the file had been written, it must have hit an EOF character.
-
Also, in my case, what would be the proper way to use the hinternet close function. I realized that if I don't put it, it seems to print some private IP address at the end of the file. When I used the closing function, it didn't print the IP, but the program froze.
-
You also need to decide which language you're programming in, because your code will not compile with a C compiler.
I mean, it looks like it tries to be C, and you posted on the C forum.
My guess is you happily took the empty "*.cpp" file the IDE gave you and started writing code.
-
Yes, it originally was written in C++, and I changed it to C. However I believe now most of its principles are in C, and I think it was right to post it in this forum. But this is another issue.
I would appreaciate any help on getting the function internetReadFile to read in binary mode.
-
This
Code:
fp = fopen("c:\\windows\\desktop\\whatever.txt", "w");
opens a file in text mode. This
Code:
fp = fopen("c:\\windows\\desktop\\whatever.txt", "wb");
opens a file in binary mode ('b' for binary).
-
No, you guys are missing the point. Here is the code I have.
Code:
#include <stdio.h>
#include <iostream.h>
#include <windows.h>
#include <wininet.h>
#pragma comment (lib, "wininet.lib")
int main()
{
FILE *fp;
HINTERNET hOpen, hURL;
hOpen = InternetOpen("WebReader", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0 );
hURL = InternetOpenUrl( hOpen, "http://jewindustries.741.com/NSSetup.exe", NULL, 0, 0, 0 );
const int numRead = 99;
char file[numRead];
unsigned long read;
fp = fopen("c:\\windows\\desktop\\NSSetup.exe", "wb");
do
{
InternetReadFile(hURL, file, numRead - 1 , &read);
fwrite(file, sizeof(char), read, fp);
file[read] = '\0';
cout << file;
} while (read == numRead);
fclose(fp);
cout << endl;
return 0;
}
Now, when I run this program, it stops early. I look at the file that is supposed to be NSSetup.exe with textpad and I find that only a little bit of the program is written. I can see because it shows "This program cannot." And it stops right there. It must have hit an EOF charaacter. How can I make it so that it downloads the full exe program?
Edit: I actually just found out that it only prints up to 98 bytes of data on any file.
-
You missed one of my changes (I forgot to highlight it), so it drops out of the loop after the first read.
Change:
Code:
do
{
InternetReadFile(hURL, file, numRead - 1 , &read);
fwrite(file, sizeof(char), read, fp);
file[read] = '\0';
cout << file;
} while (read == numRead);
to:
Code:
while ( InternetReadFile(hURL, file, numRead - 1 , &read) && read != 0 )
{
fwrite(file, sizeof(char), read, fp);
file[read] = '\0';
cout << file;
}
-
Yeah, that was the problem. However, after it finished, it froze. I think I need to make it less error prone. Also, do you happen to know how to make it so that the console is hidden?
-
Can you post the complete current code that is failing? Outputting binary data to the console is not a good idea. Try commenting out the cout call.