iCAx开思工具箱

标题: prt文件如何存入数据库,然后在再数据库中读出,在UG中显示出来 [打印本页]

作者: fengling2001    时间: 2005-5-9 16:18
标题: prt文件如何存入数据库,然后在再数据库中读出,在UG中显示出来
我是新手!!!希望大家帮忙!!!!
作者: fengling2001    时间: 2005-5-9 16:19
请高手帮助!!!!!!
作者: mizzle    时间: 2005-5-9 19:13
要把part文件的存放路径放到数据库中,然后找到,按照这个路径和文件名打开就可以了吧
作者: silencehunt    时间: 2005-5-9 19:18
正好我最近做过这方面的内容,来谈一点体会。我的项目里,数据库使用的是Oracle,在表中对应prt文件的字段是BLOB类型,所以就直接使用了Oracle提供的OO4O,如果你使用的是其它数据库,请自行查阅相关资料。
以下是我的代码,首先是将prt文件保存入数据库
  
CString strPath,strSql,strFile;
  
  OValue val;
  tag_t Tag;
  char* desc;
  char path[256];
  int closemode=0;
  UF_PART_save();//保存当前正在编辑的文件
  Tag=UF_PART_ask_display_part();//获得当前显示prt文件的tag
  UF_PART_ask_description(Tag,[$desc)]
  UF_PART_ask_part_name(Tag,path);//根据tag值获得当前文件的路径
  UF_PART_close(Tag,1,closemode);//关闭当前文件
  UF_UNDO_delete_all_marks();
  strPath=(LPCSTR)(path);
  if (strPath=="")
  {
    AfxMessageBox("当前没有被打开的文件,无法提交更新至数据库");
    return;
  }
  
       //这种情况是在数据库中新建一条记录
       
       //首先检查数据库中是否已经存在当前工序号所对应的记录,如果存在,就不进行新建操作
      strSql="select sim_pic_name,sim_pic from propicinfo where op_id='" + cur + "' and sim_pic is not null";//cur是一个CString类型的变量,从外部传入,而sim_pic就是要保存的prt文件对应的BLOB字段
      ds.Open(db,strSql);//db是一个Oracle的ODatabase,ds是一个Oracle的ODynaset,使用方法见OO4O文档
      if (ds.GetRecordCount()!=0)
      {
        AfxMessageBox("当前工序的工序简图已经存在,无法新建!");
        return;
      }
      //在新建工序图时,首先向数据库中插入包含当前工序号的一条记录
      //同时把从prt文件完整路径中获得的文件名也赋给sim_pic_name字段
      strSql="insert into propicinfo (op_id,sim_pic_name) values('" + cur + "','" + strFile + "')";
      db.ExecuteSQL(strSql);
  
      strSql="select sim_pic_name,sim_pic from propicinfo where op_id='" + cur + "' and sim_pic_name is not null";//再重新查询到刚才插入到数据库中的那条记录
      ds.Open(db,strSql);
      ds.StartEdit();
      //由于此时sim_pic字段还没有被赋值,所以其值为NULL。根据OO4O的要求,先定义一个OValue
      //然后将其值设为Emtpy(非NULL!),再将该Emtpy赋给sim_pic字段,对数据库提交更新。然后重新
      //把sim_pic字段的值赋给lob,lob是一个OBlob类型的数据
      val.SetEmpty();
      ds.SetFieldValue((const char *)"sim_pic",val);
      ds.Update();
  
      ds.StartEdit();
      ds.GetFieldValue("sim_pic",[$lob)]//把sim_pic字段与lob对象关联起来
      StreamWrite(strPath);
  
//StreamWrite是一个几乎是从OO4O的例子中照搬过来的函数,它与UG没有任何的关系,它接受的唯一参数就是要提交到数据库中的文件的路径
StreamWrite(CString strPath)
{
  
  oresult ores;
  unsigned char *buffer = 0;
        
  try
  {                 
    // calculate an optimum buffersize of approximately 32k bytes
    unsigned long optchunk = lob.GetOptimumChunkSize();
    unsigned int bufsize = ((int)(32768/optchunk)) *optchunk;
    buffer = (unsigned char *)malloc(bufsize);
    
    //open file and get file size
    fstream fs;
    fs.open(strPath, ios::in);
    fs.setmode(filebuf::binary);
    fs.seekg(0, ios::end);
    
    unsigned long filesize = fs.tellg();
    fs.seekg(0, ios::beg);
    
    unsigned long totalwritten = 0;
    unsigned long amtread = 0;
    unsigned char  piecetype = OLOB_FIRST_PIECE;
    
    //By taking advantage of streaming we get the best performance
    //and we don't need to allocate a huge buffer.
    if (filesize <= bufsize)
      piecetype = OLOB_ONE_PIECE;
    else            
      lob.EnableStreaming(filesize);
    
    while(totalwritten != filesize)
    {
      fs.read(buffer, bufsize);
      amtread = fs.gcount();
      
      lob.Write(buffer, amtread, piecetype);         
      totalwritten = totalwritten + amtread;
      
      if ((filesize - totalwritten)<=bufsize)
        piecetype = OLOB_LAST_PIECE;
      else  
        piecetype = OLOB_NEXT_PIECE;
    }
    
    lob.DisableStreaming();
    
    ores = ds.Update();
    fs.close();
  }
  catch(OException E)
  {
    cout<<E.GetFailedMethodName()<< " Error: "<<E.GetErrorText()<<endl;
  }
  
  if (buffer)
    free(buffer);
}
  
       //这种情况是在编辑数据库中已经存在的一条记录中的那个BLOB字段
       strSql="select sim_pic_name,sim_pic from propicinfo where op_id='" + cur + "' and sim_pic is not null";
  ds.Open(db,strSql);
  ds.StartEdit();
  ds.GetFieldValue("sim_pic",[$lob)]
  lob.Erase(lob.GetSize(),1);
  StreamWrite(strPath);
  
我想从上面的代码里,你应该可以看得出来,真正与数据库相关联的就是StreamWrite函数,所以只要能够获得你要送入数据库的那个文件的路径就可以了。下一帖再说如何从数据库中读出,并在UG中显示出来。
作者: silencehunt    时间: 2005-5-9 19:28
要从数据库中读出文件,并在UG中显示,实质上就是把一个BLOB字段读取出来,保存到本地硬盘上,再用UG打开这个文件就可以了。下面代码中的一些变量的定义,基本上看上一个帖子应该就都知道了。
  
strSql="select sim_pic_name,sim_pic from propicinfo where op_id='" + cur + "' and sim_pic is not null";
ds.Open(db,strSql);
  
//假设要保存到如下路径        
strPath="C:\\1234.prt";
  
ds.GetFieldValue("sim_pic",[$lob)]
StreamRead(strPath);
UF_PART_load_status_s status;
UF_PART_open(strPath,[$Tag,&status)]//用UG打开指定路径的文件
UF_free_string_array(status.n_parts,status.file_names);//释放资源
UF_free(status.statuses);
  
//同样,StreamRead也是一个几乎照搬OO4O例子的函数,接受的参数也是要保存的路径
StreamRead(CString strPath)
{
  
  unsigned char *buffer = 0;
  
  
    try
    {
        fstream fs;
        fs.open(strPath, ios::out|ios::trunc);
        fs.setmode(filebuf::binary);
    
        unsigned long size = lob.GetSize();
        
        // calculate an optimum buffersize of approximately 32k bytes
        unsigned long optchunk = lob.GetOptimumChunkSize();
    
        unsigned int bufsize = ((int)(32768/optchunk)) *optchunk;
        if (bufsize > size)
            bufsize = size;
    
        buffer = (unsigned char *)malloc(bufsize);
    
        //By taking advantage of streaming we get the best performance
        //and do not need to allocate a large buffer
        lob.EnableStreaming(size);
    
        short status= OLOB_NEED_DATA;
        unsigned long amtread=0;
        
        while(status == OLOB_NEED_DATA)
        {
      
            amtread = lob.Read([$status, buffer, bufsize)]
            fs.write(buffer, amtread);
        }
        
        lob.DisableStreaming();     
        fs.close();
    }
    catch(OException E)
    {
        cout<<E.GetFailedMethodName()<< " Error: "<<E.GetErrorText()<<endl;
    }
  
    if (buffer)
        free(buffer);
  
}
作者: silencehunt    时间: 2005-5-9 19:32
最后再说两句。从上面的代码里可以看到,这个功能的实现,在很大程度上借助了Oracle提供的OO4O的功能。如果你使用的数据库中MS SQL Server,或者数据库连接使用的是ADO,那么就要重新考虑如何去读取和写入Binary对象了,大家可以交流一下心得。
另外,在用UG打开文件之后,要释放相应的资源,在这个问题上我有一些疑惑,我的帖子在这里:https://www.icax.org/viewthread. ... %3D1&page=#pid=哪位能帮我解答一下?谢谢
作者: wangxinyush    时间: 2005-5-11 16:49
楼上那位做得太复杂了吧,在UG里有自己带的数据库
作者: silencehunt    时间: 2005-5-11 21:36
wangxinyush wrote:
楼上那位做得太复杂了吧,在UG里有自己带的数据库

是吗?仔细说说吧




欢迎光临 iCAx开思工具箱 (https://t.icax.org/) Powered by Discuz! X3.3