2

私はここで私の頭を失うことにかなり近づいています;)

gsoap を使ったサービスを開発しています。mime レスポンスを返したいと思います。私はすべてが機能していますが、バイナリファイルを読み取る場合、jpeg、pdfなどのすべての種類のファイルには\0、データに数回 char が含まれています(メモ帳で開いた場合、多くのNUL.

そのため、生ファイルを読み取るためのコードは、ファイルの終わりの文字が見つかると、惨めに失敗します。を置き換えようとしました\0が、ファイルが正しく表示されなくなります。

また、gsoap に付属の例を含むいくつかの方法を試しました。

再開しますので、

fstream 汎用コードは機能しません。

for (i = 0; i < MAX_FILE_SIZE; i++)
    { if ((c = fgetc(fd)) == EOF)
        break;
      image.__ptr[i] = c;
    } 

も機能しません

QFile::ReadAll動作しますが、配列に変換QStringすると、最初の.char*NUL

では、バイナリ ファイル全体を読み取るための最良のアプローチはどれでしょうか? 基本的に C++ がどのようにクレイジーなのか。

前もって感謝します。

retnickが以下に提案したように、私はこれを試しました

    UrlToPdf urlToPdf;  
urlToPdf.getUrl(&input, &result);  

QByteArray raw = urlToPdf.getPdf(QString(result.data.c_str()));  

int   size      = raw.toBase64().size();  
char* arraydata = new char[size];  
strcpy(arraydata, raw.toBase64().data());  

soap_set_mime(this, "MIME_boundary", NULL);  
if(soap_set_mime_attachment(this, arraydata, size, SOAP_MIME_BASE64, "application/pdf", NULL, NULL, NULL))  
{  
    soap_clr_mime(this);  

    soapMessage = this->error;  
}  

しかし、うまくいきません... MIME 応答は実際のファイルよりも大きくなります...

デビッド・G・オルテガ

4

3 に答える 3

2

バイナリファイルを読み取るには、fread()を使用 します。一度読み取ると、文字列ではなくバイトの配列として扱われます。文字列関数は使用できません。

編集:gSOAPドキュメントセクション14.1では、MIME添付ファイルを送信する方法について説明しています。関連する機能のみを参照しています(すべてお読みください)。

  int soap_set_mime_attachment(struct soap *soap, char *buf_ptr, size_t buf_size, 
        enum soap_mime_encoding encoding, 
        const char *type, const char *id, 
        const char *location, const char *description);

char *buf_ptrあなたのバッファです。 size_t buf_sizeバッファの長さです。

だからあなたのをしてくださいQFile::ReadAll

これにより、が返されますQByteArray。QByteArrayにはメソッドがあります

QByteArray QByteArray :: toBase64()const

これは

 QByteArray base64image = QByteArray::toBase64(rawImage);    

だから今だけ

soap_set_mime(soap, "MIME_boundary", "<boundary.xml@just-testing.com>"); 
/* add a base64 encoded image (base64image points to base64 data) */ 
soap_set_mime_attachment(soap, 
        base64image.data(), base64image.size(), 
        SOAP_MIME_BASE64, "image/jpeg", 
        "<boundary.jpeg@just-testing.com>", NULL, NULL); 

私はこれをテストしていませんが、ほぼ完成するはずです。

于 2010-06-21T20:38:24.030 に答える
1

QFile :: ReadAllは機能しますが、QStringをchar *に変換すると、配列は最初のNULでトリミングされます。

実際にトリミングされているのか、それともデバッガーで配列を印刷/表示できないのか(Cスタイルの文字列は0で終了しているため)?

QString自体がニーズに十分でない場合は、範囲コンストラクターまたは範囲割り当てを使用してstd :: vectorなどに変換すると、コンテナーが保持するデータの量に対する苦痛が大幅に軽減されます。

編集:バイナリファイルからfstreamを読み取るためのサンプルコードは次のとおりです。

std::ifstream image( <image_file_name>, std::ios_base::in | std::ios_base::binary );
std::istream_iterator< char > image_begin( image ), image_end;
std::vector< char > vctImage( image_begin, image_end ); 

これstd::ios_base::binaryは物事の最も重要な部分です(fopen/fread["rb"]QFileに似ており、おそらく似たようなものがあります)

また、サンプルコードを投稿すると、通常、正しい答えを得るのに役立ちます。

こんにちは

于 2010-06-21T21:14:32.803 に答える
1

私はこれに対する解決策を持っています...レニックが提案したように、私は彼のアイデアを試しましたが、それをあまり理解せずに失敗しました...論理的な観点から、レニックは正しかった...バット真実は、 QT QByteArray、std、または mem は、最初の \0 文字を見つけると停止します。Qt QString は問題なく実行できますが、C 文字列 (char*) に変換すると、データは最初の \0 で再びトリミングされます。

QDataStream::readRawData を使用すると、読み取るサイズを指定してファイルを char* に読み取ることがわかりました。そうやって取引を成立させた...

QFile file("test.pdf");
file.open(QIODevice::ReadOnly);

int         size   = file.size();
char*       buffer = new char[size];    
QDataStream stream(&file);
stream.readRawData(buffer, size);

soap_set_mime(this, "MIME_boundary", NULL);
if(soap_set_mime_attachment(this, buffer, size, SOAP_MIME_BINARY, "application/pdf", NULL, NULL, NULL))
{
    soap_clr_mime(this);

    soapMessage = this->error;
}

行に注意してください

if(soap_set_mime_attachment(this, buffer, size, SOAP_MIME_BINARY, "application/pdf", NULL, NULL, NULL))

sizeof(buffer) やその他のアプローチを行う代わりに、サイズ var を使用しています。これは、最初の \0 を見つけるためにデータ qhen を再度トリミングするためです...

お役に立てれば...

デビッド・G・オルテガ

于 2010-07-09T11:52:43.797 に答える