InternetReadFileでバイナリファイルを読み込む方法

このQ&Aのポイント
  • InternetOpen, InternetOpenURL, InternetReadFileを用いてhttp上のバイナリファイルを読みとる方法をご存知の方がいらしたら、その方法をご教示ください。
  • バイナリファイルを読み取る方法は発見できませんでした。InternetOpen, InternetOpenURL, InternetReadFileの引数も調査してみましたが、バイナリモードに該当するようなオプションは見つかりませんでした。
  • 当方をBorlandのC++Builderを使用して、InternetOpen, InternetOpenURL, InternetReadFileを用いてhttp上のテキストファイルを読むところまでは順調に動作しています。
回答を見る
  • ベストアンサー

InternetReadFileでバイナリファイルを読み込む方法

InternetOpen, InternetOpenURL, InternetReadFileを用いてhttp上のファイルを読むことはできますが、単独の0x0Aまたは0x0Dがあると、それらを0x0D+0x0Aの2バイト(MS-DOSの改行コード)に変換してしまいます。読み取りたいのはバイナリファイルなので、この変換は不要ですが、この機能を外すオプションが分かりません。ネット検索してみましたが、Visual BasicではInternetReadFile の2番目の引数であるlpBufferをString型でなくByte型にするとバイナリにすることによりバイナリファイルを読み取り可能という情報は得られたのですが、C++についてはバイナリファイルを読み取る方法は発見できませんでした。InternetOpen, InternetOpenURL, InternetReadFileの引数も調査してみましたが、バイナリモードに該当するようなオプションは見つかりませんでした。 InternetOpen, InternetOpenURL, InternetReadFileを用いてhttp上のバイナリファイルを読みとる方法をご存知の方がいらしたら、その方法をご教示ください。また、それは不可能であると確認された方がいましたら、その情報をお知らせください。 なお、当方をBorlandのC++Builderを使用して、InternetOpen, InternetOpenURL, InternetReadFileを用いてhttp上のテキストファイルを読むところまでは順調に動作しています。

質問者が選んだベストアンサー

  • ベストアンサー
  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.3

#1>0x0D+0x0Aに変換されてしまうのは0x0Aの場合のみでした 試しに、改行がLF(0x0A)で構成されるhtml ファイルで試してみましたが、そのような変換はされませんでした。(0x0Aのまま) 変換がされたと確認されているのは、InternetReadFile で取り込んだバッファの中を直接確認されているのですか?

jklm324
質問者

お礼

ご指摘ありがとう御座います。おかげさまで解決しました。 まったく恥ずかしい話ですが、格納するファイルをOpenするときに"wb"とすべきところが、"w"になっていました。同じプログラムをテキストの読み取りに使ったとき、何かのトラブルがあって、一時的に"w"にしたのが、そのままになっていたようです。

その他の回答 (2)

  • rinkun
  • ベストアンサー率44% (706/1571)
回答No.2

これはサーバ側の設定に依存します。 Webサーバはテキストをクライアントに送り出す際には改行コードをCRLFに変換します。 # これはインターネット上の取り決め(RFC)によります ダウンロードするファイルがテキストかバイナリかはWebサーバの設定によりファイルの拡張子などで判断するようになっており、特に設定されていないファイルだとテキストとして扱うサーバもあります。(多分こっちが主流) Webサーバの設定を見直し、ダウンロードするバイナリファイルを正しくバイナリファイルとして認識するようにしてください。

jklm324
質問者

お礼

たしかにサーバー側の問題という可能性もありますね。しかし、拡張子を.jpgにしても結果は同じでした。 原因は当方の初歩的なミスであることが判明しましたので、問題は解決しました。 ありがとうございました。

  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.1

http://nienie.com/~masapico/api_sample_inet04_c.html を参考にして、 C++Builder を使って、バイナリファイルを読み込んでみましたが、(特別な指定とか無くても)問題なく読み込めました。

jklm324
質問者

お礼

回答、有難うございます。しかし、教えていただいた例の通りにしても、結果は変わりませんでした。 IternetOpenの2番目の引数とInternetOpenUrlの4番目の引数が私の使用していたものと異なるので、教えていただいた例と同じにしたのですが、結果は変わりませんでした。0x0Aの前に0x0Dが追加されてしまいます。 なお、質問では「0x0Dが0x0D+0x0A」に変換されてしまうと記述しましたが、これは間違いでした。0x0D+0x0Aに変換されてしまうのは0x0Aの場合のみでした。この場を借りて訂正させていただきます。

関連するQ&A

  • InternetReadFileで大きいファイルが読み取れない

    InternetReadFileでウェブ上のファイルをローカルPCにコピーするプログラムが、ファイルサイズが大きくなると最後までコピーできません。具体的には1Mバイト以上のファイルの読み取りにおいて、150K~400Kバイトまでしか読み取ることができません。読み取られたバイト数(以下のプログラムでdwByteRead)が0になり、それ以降のデータを読み取れません。読み取られた総バイト数は読み取りバッファサイズ(以下のプログラムでREAD_BUF_SIZE)の整数倍ですが、その値は毎回異なります。(殆どの場合、150K~400Kバイト)dwByteReadが0なった後、10回再試行を行うルーチンを追加してみましたが、一旦0になるとそれ以降は復活することはなく効果無しでした。このプログラムは数10Kバイトまでの読み取りでは安定して動作しているので、プログラム自体の安定性は問題ないと思います。 InternetReadFileで1Mバイト以上のファイルを読み取ることに成功して方がいらっしゃいました、その方法をご教示ください。他の方法でも1Mバイト以上のファイルをhttpから取り込むことができる方法で結構です。 HINTERNET hSession = InternetOpen( "MyApp", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0 ); if( hSession ){ HINTERNET hService = InternetOpenUrl( hSession, url, NULL, 0, 0, 0 ); if( hService ){ ... if( (fp=fopen(fName.c_str(), "wb")) != NULL ){ fwrite( lpBuffer, dwBytesRead, 1, fp ); while(true){ Byte lpBuffer[READ_BUF_SIZE+1]; DWORD dwBytesRead = READ_BUF_SIZE; InternetReadFile( hService, lpBuffer, READ_BUF_SIZE, &dwBytesRead ); if( dwBytesRead == 0 ) break; fwrite( lpBuffer, dwBytesRead, 1, fp ); } ...

  • InternetReadFileで読み込んだECUサイトの文字化け?

    InternetOpen→InternetOpenUrl→InternetReadFileでHTMLソースを読み込んでエディットボックスに出力すると、EUCのサイトだけ文字化けします。この場合EUCからS-JISに変換して出力するのが一般的なのでしょうか? また、読み込んだHTMLソースから文字列を抜き出したりしたいのですが、この場合もEUCからS-JISに変換してから扱うのでしょうか? 初心者ですがよろしくお願いします。 VC++6.0です。

  • Wininetでのプロキシとポート指定によるファイルのダウンロード

    Wininetの下記の関数の組み合わせで、Webサーバからファイルをダウンロードしています。 InternetOpen→InternetOpenUrl→InternetReadFile(VB6.0) プロキシなしでやっているときは、問題なかったのですが、プロキシとポートを 指定したところ、うまくダウンロードできなくなりました。 InternetOpenで、プロキシの設定は行ったのですが、ポートの指定ができずに 困っています。ポートは一般的な80,8080ではなく特殊な設定になっています。 InternetConnectでポートの指定ができるようですが、うまくいきません。 どなたかお教え下さい。宜しくお願い致します。

  • バイナリエディタの自作

    バイナリエディタを自作したいのですが、 どのようにしたらいいのか検討が付きません。 正確にはBzのようなバイナリ編集画面を作成したいのです。 開発環境は「Borland Developer Studio 2006」の「c++ Builder」になります。 情報をお持ちの方がいらっしゃいましたら どうぞお力をお貸しください。 よろしくお願い致します。

  • バイナリファイルの特定のバイナリ値をカウントする方法は?

    お世話になります。 質問です。 バイナリファイルから特定のバイナリ値を抽出して、 1バイト単位でカウントする方法はありますか? (例) バイナリファイル"FileA"のバイナリ値0xffをカウントする。 <FileAの中身> 0xfe 0xff 0xff 0x12 0x00 0x00 0xff 0x01 0x00 ↑のファイルから0xffを3カウントした。 $ hexdump -v <ファイル> | grep <ターゲットの値> | wc -w (質問を書いてる現在、linux環境が無いので記憶を頼りに書いてますので間違ってると思います) ↑のようにのような方法は思いつきましたが 「一度テキストにして~grepにパイプして~wcにパイプする」となると、 ファイルサイズに依っては処理に数時間費やしてしまいます。 なので、以下の条件を満たす方法を探しています。 (1)処理の無駄が少ない(バイナリを直接探す方法等) (2)できるだけシンプルにコマンドライン一行で実現 (3)スクリプトファイルを含むソースファイルを作る作業無し よろしくお願いします。

  • Batファイルをバイナリ形式にする方法

    いつもお世話になります。 Batファイルを作ったのですが、ファイルの内容を 見せたくありません。 バイナリにしてしまえば、テキスト等では 見れなくなるので、変換方法等あればご教授 ください。 また、バイナリに変換する以外にもファイルの内容が わからなくなればいいので他によい方法があれば おしえてください。 よろしくお願いします。

  • バイナリファイルの書き出し

    バイナリファイルにデータを書き込むプログラムを作りたいと思っています。実は、Standard MIDI Fileのバイナリファイルを作りたいんです。 SMFについては、今まで、直接バイナリエディタで開き、16進数の数字をいじくって、データ書き換えたりしてたので直接バイナリファイルに16進数での数字を書きたいんです。 たとえば、テキストファイルに903C408360803C0000みたいに吐き出すプログラムでは、バイナリファイルに書き出してからバイナリエディタで開くと こいつがさらに16進数に変換されてしまいますよね? そうならないようにするにはどうやればいいんですか?

  • テキストファイルのデータからバイナリを作りたい

    現在、テキストデータとしてCSVファイル1つあたり8バイトのデータが1000個ほどのデータが書かれているファイルがあります。このデータをバイナリファイルへ数値も変換して行きたいと思っています。 たとえば1個目のデータ”12345678”というテキストデータをバイナリの"12345678"に変換したらそれを0x00番地に並べて、そして2個目のデータ”87654321”というデータをバイナリにしたらそれを0x90離れた場所に置いていき、それを1000回繰り返して、結果をバイナリファイルで出力したいのですが、何か簡単にできるフリーソフトなどありませんでしょうか? また、プログラムとかでも簡単にできるのならそうしたいのですが、どうしたらよいか教えていただけないでしょうか?

  • テキストファイルをバイナリファイルに変換

    -32768, -32768, -32768, -32768, -32768, -32768, -32768, -32768, -32768, -32768, 130, 120, 120, 109, 100, 100, 94, 91, 90, 89, 87, -32768, 78, 71, … と続いていくテキストファイルのデータをバイナリデータにC言語で変換したいのですが、どうすれば変換出来るのでしょうか。

  • InternetReadFileを使ったファイルダウンロード

    下のようなプログラムは、httpサーバから特定のファイルを ダウンロードすることが目的です。 (※referer, file名は仮のものです。) 試しに動かしてみて、転送速度が比較的速い場合には、一応問題なく ダウンロードすることができたのですが、転送速度が遅い場合には、 ファイルサイズがどんどん膨れ上がってしまいます。 問題は、InternetReadFileでブロックされることがないからだと 推測しましたが、情報が少なく困っています。 転送速度が遅い場合にも正常にダウンロードするにはどうしたら よいでしょうか? #include <windows.h> #include <wininet.h> #include <stdio.h> #include <stdlib.h> bool GetHttpFile(){   HINTERNET hInternet;   HINTERNET hFile;   char Buf[1000]; /* バッファ */   DWORD ReadSize;   BOOL bResult;   wchar_t szHead[] = TEXT("Referer:http://aaa.com/\r\n\r\n"); // ヘッダにRefererを追加する   FILE *fp;   bool ret;   /* 保存先ファイル作成/open */     fp = fopen("sample.zip", "wb");   if (fp == NULL){  /* ファイル作成/openに失敗 */     ret = false;        }else{ /* ファイル作成/openに成功 */     /* WININET初期化 */     hInternet = InternetOpen(       TEXT("Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)"),       INTERNET_OPEN_TYPE_PRECONFIG,       NULL,       NULL,       0);        /* URLのオープン */     hFile = InternetOpenUrl(       hInternet,       TEXT("http://aaa.com/bbb.zip"),       szHead,       0,       INTERNET_FLAG_RELOAD,       0);        /* オープンしたURLからデータを(1000バイトずつ)読み込む */     for(;;){       ReadSize = 1000;          bResult = InternetReadFile(         hFile,         Buf,         1000,         &ReadSize);          /* 全て読み込んだらループを抜ける */       if(bResult && (ReadSize == 0)) break;              /* ファイルに書き込み */       fwrite(Buf, sizeof(char), 1000, fp);     }        /* 後処理 */     InternetCloseHandle(hFile);     InternetCloseHandle(hInternet);     fclose(fp);     ret = true;   }      return ret; } int main(){   if(GetHttpFile() == true){     printf("成功\n");   }else{     printf("失敗\n");   }      return 0; }

専門家に質問してみよう