BCB实现文件上传下载(转)

1. INDY的安装
 
  Internet Direct,一个开源的IDE网络应用组件,支持客户端、服务端、TCP、UDP、原始套接字等操作,组件包括SMTP、POP3、NNTP、HTTP、FTP等应用。

  在BCB6下安装过程如下:

  A. 删除旧indy组件:使用BCB6安装光盘,在自启动选项中选择Modify。在"Program Maintenance"中取消Indy,下一步后安装程序删除Indy组件。

  B. 下载新版本Indy:从http://www.indyproject.org/选择Indy_9_00_17_src.zip版本下载,因为该版本提供自动编译的bat文件。

  C. 自动编译Indy:解压下载的源码包,能见一个src目录。将该解压包调整至"C:/indy/"目录中,即源码目录为"C:/indy"。源码目录中有多个bat文件,执行对应批处理,如对应BCB6则执行Fullc6.bat。编译完毕后indy目录下会多出一个编译结果和头文件、库文件组成的目录"C:/indy/C6"。

  D. BCB添加新版本Indy:启动BCB修改配置信息

  菜单"Tools/Environment Options/Library"中,将"C:/indy/C6"添加至"Library Path";

  菜单"Project/Options/Packages"中,手动添加"C:/indy/C6"dclIndy60.bpl;

  菜单"Project/Options/Directories"中,将"C:/indy/C6"添加至"Include Path"和"Library Path";

  按确认退出前选择对话框左下角"Default"选项,然后"OK"退出;

  重启BCB IDE,不报错说明安装正常。

  E. 对于使用旧版本Indy开发的程序,在新环境下重新编译执行会出现"无法定位程序输入点@Idwinsock@initialization$qqr",可以通过将项目从Debug调整至Release,或者不预编译等方法,使程序完全从新版本Indy头、库文件编译,该现象会消失。

 

  如果是BCB5,不用删除以前BCB中的INDY,参考前面的执行Fullc5.bat,生成C5目录,启动BCB,在Component菜单下选择Install Packages ...进行安装即可

 

2. 测试程序编写如下,所需要的INDY组件有TIdHTTP、TIdAntiFreeze、TIdMultiPartFormDataStream,下面用一段简单的代码进行说明

/*Unit1.h*/

__published:

  TIdHTTP *IdHTTP1;//POT/GET对象

  TButton *Button1;//测试入口

  TEdit *Edit1;//返回结果并随时显示上传进度

  TProgressBar *pbS;//显示工作的进度条

  TIdAntiFreeze *IdAntiFreeze1;//TIdHTTP 工作时其它程序可以运行

  TTimer *Timer1;//简单进行进度条控制,建议不用Timer

  void __fastcall Button1Click(TObject *Sender);
  void __fastcall Timer1Timer(TObject *Sender);

private: // User declarations
    TIdMultiPartFormDataStream *stream;//上传时数据封装对象

 

/*Unit1.cpp*/

void __fastcall TForm1::Button1Click(TObject *Sender)
{
 stream = new TIdMultiPartFormDataStream();
 IdHTTP1 = new TIdHTTP(NULL);
 try{
  stream->AddFormField("FieldName","file"); //file与处理input名称一致
  stream->AddFile("FiledName","C://1.gif","multipart/form-data");
  stream->Position = 0;
  pbS->Position = 0;
  pbS->Max =  stream->Size;
  IdAntiFreeze1->OnlyWhenIdle = false;
  Timer1->Enabled = true;
  IdHTTP1->Request->ContentType = "multipart/form-data";
  Edit1->Text = IdHTTP1->Post("http://127.0.0.1/scripts/index.jsp",stream);
  Timer1->Enabled = false;
 }__finally{
  stream->Free();
  IdHTTP1->Free();
 }

}

//---------------------------------------------------------------------------
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
  pbS->Position = stream->Position;
  Edit1->Text = IntToStr(pbS->Position)+"//"+pbS->Max;
}

 

3. 在WEB端编写上传文件处理文件如上面的index.jsp

使用jspsmart处理代码如下

<%@ page import="com.jspsmart.upload.*,common.TextHandle"%><%
boolean isOK = false;

//程序初始化--------------------------------------------------------------
String path_tmp = request.getRealPath("/") + "Upload";
String filename_p = TextHandle.getDirectory();
String path_new = request.getRealPath("/") + "Upload//" + filename_p;

//文件上传----------------------------------------------------------------
SmartUpload su = new SmartUpload();
su.initialize(pageContext);
su.upload();
int count = su.save(path_tmp);

String file_name = "",file_ext,newFileName = "无";

isOK=true;

if(count>0){
    com.jspsmart.upload.File file = su.getFiles().getFile(0);
    if (!file.isMissing()){            //有上传的文件------------------------
        file_name = file.getFileName().toLowerCase();

        if(file.getSize() == 0){            //如果传来的是空文件则删除------------
            java.io.File fileName1=new java.io.File(path_tmp,file_name);
            if(fileName1.exists())     fileName1.delete();
            isOK=false;
        }
        else{                        //看是否是正确的文件------------------
            file_ext = file_name.substring(file_name.lastIndexOf(".")+1,file_name.length());
            if(file_ext.equals("jpg")||file_ext.equals("gif")||file_ext.equals("jpeg")){
                String number = String.valueOf( (new java.util.Date()).getTime() );
                newFileName = filename_p + number + "." + file_ext;
                //将文件换名保存------------------------------------------
                //首先看目录是否存在,如果不存在则创建目录
                java.io.File dirOp = new java.io.File(path_new);
                if(!dirOp.exists()) dirOp.mkdir();

                String path1 = path_tmp + "//" + file_name;
                String path2 = path_new + "//" + newFileName;
                java.io.File fromFile = new java.io.File(path1);
                java.io.File toFile = new java.io.File(path2);
                java.io.FileInputStream fis = null;
                java.io.FileOutputStream fos = null;
                try{
                    fis = new java.io.FileInputStream(fromFile);
                    fos = new java.io.FileOutputStream(toFile);
                    int bytesRead;
                    byte[] buf = new byte[4 * 1024]; // 4K buffer ---------
                    while ((bytesRead = fis.read(buf)) != -1) fos.write(buf, 0, bytesRead);
                    fos.close(); fis.close();
                }
                catch(java.io.IOException e){
                    System.out.println(e);
                }
            }else isOK = false;
            //将临时文件删除-----------------------------------------------
            java.io.File fileName_del=new java.io.File(path_tmp,file_name);
            if(fileName_del.exists())     fileName_del.delete();       
        }
    }
    else{//上传文件不成功--------------------------------------------------
        isOK=false;                   
    }
}
else{//无文件上传----------------------------------------------------------
    isOK = false;
}

//进行数据库操作-----------------------------------------------------------
if(isOK) out.print("OK:["+newFileName+"]"); else out.print("NONONONONONONONONONONONONONONONONONONONONO");
%>

 

补充建议:为确保旧Indy彻底删除,建议删除以下文件(删除前注意先不要彻底删除):
安装目录下的以下文件dclindy*.bpl; dclindy.*; dclindy*.bpl; indy*.lib; indy*.bpl; indy*.dll; id*.pas; id*.hpp;  id*.dcu; id*.obj; (除IDPAS32.obj外)
Windows安装目录下System32目录下indy*.bpl 删除

删除CB暗转目录下Source/Indy 内的所有文件

 

另一错误:如果程序编译顺利通过,而运行时出堆栈错误
解决方法:菜单“Project”,选“Edit Options Source”,将打开XML格式的工程配置源文件。搜索所有indy.bpl字样,并删除;然后菜单Project->Options,找到“Packages”页,在下方的“Runtime packages”编辑框内,找到“indy60”,删除。最直接的方法是直接取消“Build with Runtime packages”复选框即可]]

文件下载方法:

    AnsiString = "http://www.blog.163.com/lxz_jlu/";

    if(SaveDialog1->Execute()){
        TFileStream *downFile = new TFileStream(SaveDialog1->FileName,fmCreate);
        IdAntiFreeze1->OnlyWhenIdle = false;
        IdHTTP1->Get(memMain->Lines->Strings[recordIndex],downFile);
        downFile->Free();
        ShowMessage("页面http://www.blog.163.com/lxz_jlu/下载成功!/n保存路径:"+SaveDialog1->FileName);
    }

你可能感兴趣的:(BCB实现文件上传下载(转))