C++ 使用协议缓冲区从文件读取消息时出现问题

C++ 使用协议缓冲区从文件读取消息时出现问题,c++,protocol-buffers,C++,Protocol Buffers,我正在尝试使用从一个文件中读取多条消息。文档使用CodedInputStream 但是,如果我试着阅读一条非常小的信息,我就会从中失败 例如,如果我将消息定义为: message Chunk { repeated int64 values = 1 [packed=true]; } 并尝试将消息写入文件,然后将其读回: int main() { GOOGLE_PROTOBUF_VERIFY_VERSION; { Chunk chunk; for (int i

我正在尝试使用从一个文件中读取多条消息。文档使用
CodedInputStream

但是,如果我试着阅读一条非常小的信息,我就会从中失败

例如,如果我将消息定义为:

message Chunk {
  repeated int64 values = 1 [packed=true];
}
并尝试将消息写入文件,然后将其读回:

int main() {
  GOOGLE_PROTOBUF_VERIFY_VERSION;
  {
      Chunk chunk;
      for (int i = 0; i != 26; ++i)
        chunk.add_values(i);

      std::ofstream output("D:\\temp.bin");
      OstreamOutputStream raw_output(&output);

      if (!writeDelimitedTo(chunk, &raw_output)){
        std::cout << "Unable to write chunk\n";
        return 1;
      }
  }
  {
    std::ifstream input("D:\\temp.bin");
    IstreamInputStream raw_input(&input);
    Chunk in_chunk;

    if (!readDelimitedFrom(&raw_input, &in_chunk)) { // <--- Fails here
      std::cout << "Unable to read chunk\n";
      return 1;
    }

    std::cout << "Num values in chunk " << in_chunk.values_size() << "\n";
  }

  google::protobuf::ShutdownProtobufLibrary();
}
如果我只在我的消息中写入25个值,它会工作,26个值,它就会失败。我已经在代码中显示了它失败的地方

我试着调试protobuf库,它似乎无法将新数据读入缓冲区,但我不知道为什么


我正在使用Visual Studio 2013和protobuf 2.6.1

正如@rashimoto正确指出的,我无法以二进制模式打开文件

通过该修复,我可以成功地将多条消息写入文件:

int main() {
  GOOGLE_PROTOBUF_VERIFY_VERSION;
  {
    std::vector<Chunk> chunks = createChunks(NUM_CHUNKS, CHUNK_SIZE);

    std::ofstream output("D:\\temp.bin", std::ios::binary);
    OstreamOutputStream raw_output(&output);

    for (Chunk& chunk : chunks) {
      if (!writeDelimitedTo(chunk, &raw_output)){
        std::cout << "Unable to write chunk\n";
        return 1;
      }
    }
  }
  {
    std::ifstream input("D:\\temp.bin", std::ios::binary);
    IstreamInputStream raw_input(&input);
    std::vector<Chunk> chunks(NUM_CHUNKS);

    for (auto& chunk : chunks) {
      if (!readDelimitedFrom(&raw_input, &chunk)) {
        std::cout << "Unable to read chunk\n";
        return 1;
      }
    }

    std::cout << "Num values in first chunk " << chunks[0].values_size() << "\n";
  }

  google::protobuf::ShutdownProtobufLibrary();
}
intmain(){
谷歌协议验证版本;
{
std::vector chunks=createChunks(NUM\u chunks,CHUNK\u SIZE);
流输出的std::of(“D:\\temp.bin”,std::ios::binary);
OstreamOutputStream原始输出(&output);
for(块和块:块){
如果(!writedLimitedTo(块和原始输出)){

正如@rashimoto正确指出的,我无法以二进制模式打开文件

通过该修复,我可以成功地将多条消息写入文件:

int main() {
  GOOGLE_PROTOBUF_VERIFY_VERSION;
  {
    std::vector<Chunk> chunks = createChunks(NUM_CHUNKS, CHUNK_SIZE);

    std::ofstream output("D:\\temp.bin", std::ios::binary);
    OstreamOutputStream raw_output(&output);

    for (Chunk& chunk : chunks) {
      if (!writeDelimitedTo(chunk, &raw_output)){
        std::cout << "Unable to write chunk\n";
        return 1;
      }
    }
  }
  {
    std::ifstream input("D:\\temp.bin", std::ios::binary);
    IstreamInputStream raw_input(&input);
    std::vector<Chunk> chunks(NUM_CHUNKS);

    for (auto& chunk : chunks) {
      if (!readDelimitedFrom(&raw_input, &chunk)) {
        std::cout << "Unable to read chunk\n";
        return 1;
      }
    }

    std::cout << "Num values in first chunk " << chunks[0].values_size() << "\n";
  }

  google::protobuf::ShutdownProtobufLibrary();
}
intmain(){
谷歌协议验证版本;
{
std::vector chunks=createChunks(NUM\u chunks,CHUNK\u SIZE);
流输出的std::of(“D:\\temp.bin”,std::ios::binary);
OstreamOutputStream原始输出(&output);
for(块和块:块){
如果(!writedLimitedTo(块和原始输出)){

std::你是说你改变了
main()
顶部的循环,这样限制就从
i!=26;
变成了
i!=30;
这样的东西,你就不能读取你添加的30个值了吗?
MergeFromCodedStream()产生了错误代码吗
function?如果在消息中写入较小数量的值(比如22),会发生什么情况?顺便说一下,我建议您修改两个函数
writeDelimitedTo()
readDelimitedFrom())
返回一个特定的错误代码,该代码将指示函数在什么时候失败,而不仅仅是返回一个
bool
@RichardChambers,基本上,是的。如果我将循环更改为
I!=25
,它将按预期工作。如前所述,
I!=26
则失败。
MergeFromCodedStream
不会返回错误代码作为fAr:我知道,只是一个布尔值来指示成功或失败。你可能需要添加<代码> STD::IOS/<代码>你的代码> STD::“OFFROWS 和 STD::IfSturis构造函数。当然,RasHimoto AH,当然!使用C++的例子显示了使用<代码> STD::iOS:< Tunc< /C> >以及<>代码:STD::iOS::二进制< /Cord>在创建和写入输出文件时。您是说您更改了
main()
顶部的循环,以便将限制从
i!=26;
更改为其他内容,例如
i!=30;
,并且您无法读取添加的30个值吗?
MergeFromCodedStream()是否产生了错误代码
function?如果在消息中写入较小数量的值(比如22),会发生什么情况?顺便说一下,我建议您修改两个函数
writeDelimitedTo()
readDelimitedFrom())
返回一个特定的错误代码,该代码将指示函数在什么时候失败,而不仅仅是返回一个
bool
@RichardChambers,基本上,是的。如果我将循环更改为
I!=25
,它将按预期工作。如前所述,
I!=26
则失败。
MergeFromCodedStream
不会返回错误代码作为fAr:我知道,只是一个布尔值来指示成功或失败。你可能需要添加<代码> STD::IOS/<代码>你的代码> STD::“OFFROWS
STD::IfSturis构造函数。当然,RasHimoto AH,当然!使用C++的例子显示了使用<代码> STD::iOS:< Tunc< /C> >以及<>代码:STD::iOS::二进制< /Cord>在创建和写入输出文件时。您是说您更改了
main()
顶部的循环,以便将限制从
i!=26;
更改为其他内容,例如
i!=30;
,并且您无法读取添加的30个值吗?
MergeFromCodedStream()是否产生了错误代码
function?如果在消息中写入较小数量的值(比如22),会发生什么情况?顺便说一下,我建议您修改两个函数
writeDelimitedTo()
readDelimitedFrom())
返回一个特定的错误代码,该代码将指示函数在什么时候失败,而不仅仅是返回一个
bool
@RichardChambers,基本上,是的。如果我将循环更改为
I!=25
,它将按预期工作。如前所述,
I!=26
则失败。
MergeFromCodedStream
不会返回错误代码作为fAr:我知道,只是一个布尔值来指示成功或失败。你可能需要添加<代码> STD::IOS/<代码>你的代码> STD::“OFFROWS
STD::IfSturis构造函数。当然,RasHimoto AH,当然!使用C++的例子显示了使用<代码> STD::iOS:< Tunc< /C> >以及<>代码:STD::iOS::二进制< /Cord>创建和写入输出文件时。