• protobuf传文件存入oracle


     

    前台加载一个文件到打包到protobuf中:

    public static Intf_R upload_file(int iInsId, int iBizType, int iMenuType, string sFileName, string sRemark)

    {

    request_p_file_upload.Builder req = new request_p_file_upload.Builder();

    request_p_file_upload_p1.Builder target = new request_p_file_upload_p1.Builder();

    target.InsId = iInsId;

    target.OisBizType = iBizType;

    target.OisMenuType = iBizType;

    target.OisBizType = iMenuType;

    target.FileName = sFileName;

    target.Remark = sRemark;

    byte[] ctrlBuffer = File.ReadAllBytes(sFileName);

    int fileSize = ctrlBuffer.Length;

    int file0ffset = 0;

    target.FileContent = ByteString.CopyFrom(ctrlBuffer, file0ffset, fileSize);

    req.AddList1(target);

     

    AmqpMessage in_msg = new AmqpMessage() { Content = req.Build().ToByteArray() };

    IAmqpMessage result = Global.Get<ICOMM>().Send("asf.biz","p_file_upload", in_msg);

    response_p_file_upload rsp = response_p_file_upload.ParseFrom(result.Content);

    IList<response_p_file_upload_p1> queryList = rsp.List1List;

    Intf_R ros = new Intf_R();

    foreach (var item in queryList)

    {

    ros.ID = item.ErrorId;

    ros.BizErrorinfo = item.ErrorMsg;

    }

    return ros;

    }

     

    关键代码已经加粗,使用protobuf的ByteString加载一段二进制流;

    后台处理代码:

    void write_p_file_upload::execute()

    {

        

        request->ParseFromArray(in->getContent(), in->getContentSize());

        LOGWARN("request: " << request->DebugString());

        string user_token = in->getProperty("user_token");

        

        iociconnection* conn = context->get_oracle_connection();

        ocilib::Connection* cn = conn->get_connection();

        ocilib::Statement st(*cn);

        string sql = "insert into tinsfile(ins_op_id,ins_id,ois_biz_type,ois_menu_type,file_name,remark,user_id,op_date,op_time,file_content) "

            "values (:ins_op_id, :ins_id, :ois_biz_type, :ois_menu_type, :file_name, :remark, :user_id, "

            "to_number(to_char(SYSDATE,'YYYYMMDD')), to_number(to_char(SYSDATE,'HH24mmss')), :file_content) ";

        st.Prepare(sql);

     

        long long ins_op_id = get_seq_id("seq_ins_op_id", context->get_plugin_context());

        int ins_id = request->list1().Get(0).ins_id();

        int ois_biz_type = request->list1().Get(0).ois_biz_type();

        int ois_menu_type = request->list1().Get(0).ois_menu_type();

        ocilib::ostring file_name = request->list1().Get(0).file_name();

        ocilib::ostring remark = request->list1().Get(0).remark();

        int user_id = 0;

        string user_id_str = in->getProperty("user_id");

        if (user_id_str.empty())

        {

            user_id = 0;

        }

        else

        {

            user_id = boost::lexical_cast<long long>(user_id_str);

        }

     

     

        ocilib::Blob file_content(*cn);

        vector<unsigned char> list;

        int sLen = request->list1(0).file_content().length();

        LOGWARN("sLen = " << sLen);

    //    list.resize(sLen);//会出现插入00字节的问题

        LOGWARN("list size = " << list.size());    

        for (int i = 0; i < sLen; i++)

        {

            list.push_back(request->list1(0).file_content().at(i));

        }

        LOGWARN("list date size = " << list.size());

        int iCnt = file_content.Write(list);

        file_content.Seek(ocilib::SeekModeValues::SeekSet, 0);

        LOGWARN("Blob len = " << file_content.GetLength() << ", iCnt = " << iCnt);

        st.Bind<long long>(":ins_op_id", ins_op_id, ocilib::BindInfo::InOut);

        st.Bind<int>(":ins_id", ins_id, ocilib::BindInfo::InOut);

        st.Bind<int>(":ois_biz_type", ois_biz_type, ocilib::BindInfo::InOut);

        st.Bind<int>(":ois_menu_type", ois_menu_type, ocilib::BindInfo::InOut);

        st.Bind<ocilib::ostring,int>(":file_name", file_name, 1024, ocilib::BindInfo::InOut);

        st.Bind<ocilib::ostring, int>(":remark", remark, 1024, ocilib::BindInfo::InOut);

        st.Bind<int>(":user_id", user_id, ocilib::BindInfo::InOut);

        st.Bind<ocilib::Blob>(":file_content", file_content, ocilib::BindInfo::InOut);

        LOGWARN("sql: " << st.GetSql());

        st.ExecutePrepared();

        cn->Commit();

        int iRow = st.GetAffectedRows();

        if (iRow == 0)

        {

            response_p_file_upload_p1 * out1 = response->add_list1();

            out1->set_error_id(-1);

            out1->set_error_msg("上传附件失败,请重试");

        }

        else

        {

            response_p_file_upload_p1 * out1 = response->add_list1();

            out1->set_error_id(0);

            out1->set_error_msg("");

        }

        LOGWARN("response: " << response->DebugString());

    }

     

    加粗部分表示关键代码;

    从oracle取出文件打包返回给前台:

    void write_p_file_download::execute()

    {

        request->ParseFromArray(in->getContent(), in->getContentSize());

        LOGWARN("request: " << request->DebugString());

        string user_token = in->getProperty("user_token");

     

        iociconnection* conn = context->get_oracle_connection();

        ocilib::Connection* cn = conn->get_connection();

        ocilib::Statement st(*cn);

        string sql = "select file_content from tinsfile where ins_op_id = :ins_op_id ";

        st.Prepare(sql);

     

        int ins_op_id = request->list1().Get(0).ins_op_id();

        

     

        ocilib::Blob file_content(*cn);

        st.Bind<int>(":ins_op_id", ins_op_id, ocilib::BindInfo::InOut);

        st.ExecutePrepared();

        ocilib::Resultset rs = st.GetResultset();

        if (rs.IsNull())

        {

            response_p_file_download_p1 * out1 = response->add_list1();

            out1->set_error_id(-1);

            out1->set_error_msg("未能找到对应附件");

            out1->set_file_content(" ");

        }

        else

        {

            while (rs++)

            {

                file_content = rs.Get<ocilib::Blob>("file_content");

                LOGWARN("Blob len = " << file_content.GetLength());

            }

            ocilib::Raw raw = file_content.Read(file_content.GetLength());

            LOGWARN("raw size = " << raw.size());

            string sFileContent;

            int iPos = 0;

            for (int i = 0; i < raw.size(); i++)

            {

                if (raw[i] != '')

                {

                    iPos = i;

                    break;

                }

            }

            for (int i = iPos; i < raw.size(); i++)

            {

                sFileContent.push_back(raw[i]);

            }

     

            response_p_file_download_p1 * out1 = response->add_list1();

            out1->set_error_id(0);

            out1->set_error_msg("");

            out1->set_file_content(sFileContent);

        }

        LOGWARN("response: " << response->DebugString());

    }

    关键点是std::string中可以存储任意字节,这个和char数组是有区别的;

    C#前端重新保存成文件的代码如下:

    public static string download_file(int iInsId)

    {

    request_p_file_download.Builder req = new request_p_file_download.Builder();

    request_p_file_download_p1.Builder target = new request_p_file_download_p1.Builder();

    target.InsOpId = iInsId;

    req.AddList1(target);

    AmqpMessage in_msg = new AmqpMessage() { Content = req.Build().ToByteArray() };

    IAmqpMessage result = Global.Get<ICOMM>().Send("asf.biz", "p_file_download", in_msg);

    response_p_file_download rsp = response_p_file_download.ParseFrom(result.Content);

    IList<response_p_file_download_p1> queryList = rsp.List1List;

    string path = "";

    if (queryList.Count > 0)

    {

    if (!string.IsNullOrEmpty(queryList[0].FileContent.ToStringUtf8()))

    {

    path = "./file.tmp";

    using (FileStream _fs = new FileStream(path, FileMode.Append, FileAccess.Write, FileShare.Read, 1048576, FileOptions.None))

    {

    queryList[0].FileContent.WriteTo(_fs);

    }

    }

    }

    return path;

    }

     

     

     

     

     

     

     

     

     

  • 相关阅读:
    自建 IPA 分发平台
    一个优雅的占位图解决方案。适用于 UITableView 和 UICollectionView。
    Vuejs2.0购物车和地址选配学习笔记
    UIWebView 加 MJRefresh 同时解决底部黑影问题
    UIWebView 不自动全屏播放视频
    左右分页按钮的集合视图控件。用于快速编写出集合视图上分页多按钮点击事件!
    课程总结
    IO流实训
    事件处理
    变色
  • 原文地址:https://www.cnblogs.com/skiing886/p/8443759.html
Copyright © 2020-2023  润新知