我做了一个关于文件传输的程序,但是只能传送几十兆以内的小型文件,我想通过文件分段传输实现大型文件的传输,希望大家帮帮忙!先谢了。

解决方案 »

  1.   

    找出“只能传送几十兆以内”的原因。分包,其实就是一次从文件当中读一块(由于网络的速度是有限的,所以没有任何必要把整个文件几十几百兆一次性读入内存,这个内存消耗是非必要的),然后发送,再读一块。一般只要保留文件的句柄就不需要作任何动作,直接readfile就可以(读文件的时候也不可能是你想读多少就一定能给你读取出来的,而是通过返回值告诉你读取了多少,此时你可能需要继续读取,而你也可以先把读完的发送了,再继续读取。另外文件也可以通过seek或者SetFilePointer设置文件指针,于是你就可以在任意时间里进行选择性地发送某一段或某几段。
      

  2.   

    简单点的方式,用TCP协议建立连接,打开文件,做一个循环,每次读一小段数据,发送出去,再循环。
      

  3.   

    我对文件分段了,代码如下,在程序运行的时候只能打开4096k以下的文件(我把文件分成4096一块)。
    length=strlen(sFname);  //获取文件名长度
    //发送文件名长度
    sendmessage(csock,(const char*)&length,sizeof(int));
    //发送文件名
    sendmessage(csock,sFname,length);
    file.open(filename,ios::binary); //用二进制打开文件
    if(file.fail())
    {
    MessageBox("文件打开失败!");
    goto EXIT;
    }
    fb=file.rdbuf();
    length=fb->seekoff(0,ios::end,ios::in)-fb->seekoff(0,ios::beg,ios::in);
    fb->seekoff(0,ios::beg,ios::in);  //获取文件长度
    //发送文件大小
    sendmessage(csock,(const char*)&length,sizeof(int));
    bRet=TRUE;
    char data[4097];
    while(length>0)
    {
    int len=0;
            if(length <= 4096)
    {
    len = length;
    }
    else
    {
    len = 4096;
    }
    //准备缓冲区
    // data=new char[len];
    file.read(data,len);
    // data[length] = '\0';
    //发送整个文件
    bRet=sendmessage(csock, data, len);
    length -= len;
    // delete[] data;
    } file.close();
    if(bRet){
    // MessageBox("发送成功!");
    }
    else{
    MessageBox("发送失败!");
    }
    希望大家不吝指教。谢谢!
      

  4.   

    你能帮我改一改吗,或用API帮我写一个,谢谢 。
      

  5.   

    API可以查MSDN
    CreateFile打开文件
    SetFilePointer(相当于seekoff)
    ReadFile读文件
    CloseHandle关闭文件句柄。
      

  6.   

    我在做文件操作时一般都是用API的,不过CFile应该也没问题,你是open的时候返回false吗?
      

  7.   

    文件open的时候没有返回false,只是卡住不动了。
      

  8.   

    file.open(filename,ios::binary); 确定路径正确,除了2进制,带必要的读写参数
      

  9.   

    看看思路了,呵呵!
    NGCMDHEADER header;
    status stsCode = statusOk;
    FILE* fp = NULL;
    // Open file
    fp = fopen(strFileName.c_str(), "rb");
    if (fp == NULL)
    {
    return statusCreateFileError;
    }
    //
    char szDataBuf[MAX_DATABUF_LEN];
    size_t dwItem = 0;
    // 
    header.dwCmd = CMD_FDDATA;
    // Send file data
    while (true)
    {
    dwItem = fread(szDataBuf, sizeof(char), MAX_DATABUF_LEN, fp);
    header.dwBufLen = dwItem;
    stsCode = socket.SendExact((char*)&header, sizeof(header));
    if (stsCode != statusOk)
    {
    break;
    }
    stsCode = socket.SendExact(szDataBuf, dwItem);
    if (stsCode != statusOk)
    {
    break;
    }
    if (dwItem < MAX_DATABUF_LEN)
    {
    header.dwCmd = CMD_FDEND;
    header.dwBufLen = 0;
    stsCode = socket.SendExact((char*)&header, sizeof(header));
    LogFileTransferInfo(LOG_FILE, strFileName, ts.nCurFileTransferedSize);
    break;
    }
    // update information
    ts.nCurFileTransferedSize += header.dwBufLen;
    SendMessage(GetMsgProcHwnd(), WM_TASK_STATUS_UPDATE, STATUS_UPDATE_FILE, (LPARAM)&ts);
    }
    // Close file & socket
    fclose(fp); char Ext[6];
    char szFileName[MAX_PATH];
    strcpy(szFileName,strFileName.c_str());
     _GetFileExtName(szFileName,Ext);
     if( strcmp(Ext,".NSOFT") ==0 )
     {
     ::DeleteFile(szFileName);
     } return stsCode;
    }