微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何使用unique_ptr创建blob流?

如何解决如何使用unique_ptr创建blob流?

使用以下代码时,我成功地将图像保存到“图像”blob 字段中:

if (OpenDialog1->Execute()) {
    ADOTable1->Insert();
    TStream* BlobStream = ADOTable1->CreateBlobStream(ADOTable1->FieldByName("Image"),bmWrite);
    std::unique_ptr<TFileStream> FileStream(new TFileStream(OpenDialog1->FileName,fmOpenRead));
    BlobStream->copyFrom(FileStream.get(),FileStream->Size);
    delete BlobStream;
    ADOTable1->Post();
}

但是,我也希望使用 BlobStream 创建 std:unique_ptr 对象,这样我就可以避免手动 delete。当我尝试

if (OpenDialog1->Execute()) {
    ADOTable1->Insert();
    std::unique_ptr<TStream> BlobStream(ADOTable1->CreateBlobStream(ADOTable1->FieldByName("Image"),bmWrite));
    std::unique_ptr<TFileStream> FileStream(new TFileStream(OpenDialog1->FileName,FileStream->Size);
    ADOTable1->Post();
}

我收到无法插入空行错误。我在这里做错了什么?我使用的是 C++ Builder 10.3.3。

解决方法

在原始代码中,您在调用 delete 之前TStream 正在处理 blob Post() 对象。

根据 TADOBlobStream 文档:

http://docwiki.embarcadero.com/Libraries/en/Data.Win.ADODB.TADOBlobStream.Destroy

Destroy [即析构函数] 执行以下任务:

  • 设置字段的数据。

  • 将字段对象的 Modified 属性更改为 true。

  • 在字段的数据集对象中触发字段更改事件。

  • 调用继承的析构函数。

因此,您在 Post() 之前设置了 blob 的字段数据,一切都很好。

在更新后的代码中,当 delete 在调用 TStream超出范围时,您正在 BlobStream 处理 blob Post() 对象。因此,尚未设置字段数据,因此出现错误。

要确保 blob TStream 对象在调用 Post() 之前被破坏,您可以:

  • BlobStream 周围放置一个新范围:
if (OpenDialog1->Execute()) {
    std::unique_ptr<TFileStream> FileStream(new TFileStream(OpenDialog1->FileName,fmOpenRead));
    ADOTable1->Insert();
    {
    std::unique_ptr<TStream> BlobStream(ADOTable1->CreateBlobStream(ADOTable1->FieldByName("Image"),bmWrite));
    BlobStream->CopyFrom(FileStream.get(),FileStream->Size);
    }
    ADOTable1->Post();
}
  • BlobStream 上手动调用 reset()
if (OpenDialog1->Execute()) {
    std::unique_ptr<TFileStream> FileStream(new TFileStream(OpenDialog1->FileName,fmOpenRead));
    ADOTable1->Insert();
    std::unique_ptr<TStream> BlobStream(ADOTable1->CreateBlobStream(ADOTable1->FieldByName("Image"),FileStream->Size);
    BlobStream.reset();
    ADOTable1->Post();
}

无论哪种方式,您都应该进行一些错误处理,以便您可以Cancel() 插入新行,如果在可以Post() 之前发生意外情况,例如:

if (OpenDialog1->Execute()) {
    std::unique_ptr<TFileStream> FileStream(new TFileStream(OpenDialog1->FileName,fmOpenRead));
    ADOTable1->Insert();
    try {
        std::unique_ptr<TStream> BlobStream(ADOTable1->CreateBlobStream(ADOTable1->FieldByName("Image"),bmWrite));
        BlobStream->CopyFrom(FileStream.get(),FileStream->Size);
        BlobStream.reset();
        ADOTable1->Post();
    }
    catch (const Exception &) {
        ADOTable1->Cancel();
        throw;
    }
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。