C++ 分割大文件
我正在开发一个分布式系统,在该系统中,服务器将把一个巨大的任务分发给客户端,客户端将处理这些任务并返回结果。C++ 分割大文件,c++,read-write,C++,Read Write,我正在开发一个分布式系统,在该系统中,服务器将把一个巨大的任务分发给客户端,客户端将处理这些任务并返回结果。 服务器必须接受20Gb大小的巨大文件 服务器必须将此文件拆分为较小的部分,并将路径发送给客户端,客户端将依次scp文件并处理它们 我正在使用read和write执行文件拆分,这执行起来非常慢 代码 //fildes - Source File handle //offset - The point from which the split to be made //buffersiz
服务器必须接受20Gb大小的巨大文件 服务器必须将此文件拆分为较小的部分,并将路径发送给客户端,客户端将依次scp文件并处理它们 我正在使用
read
和write
执行文件拆分,这执行起来非常慢
代码
//fildes - Source File handle
//offset - The point from which the split to be made
//buffersize - How much to split
//This functions is called in a for loop
void chunkFile(int fildes, char* filePath, int client_id, unsigned long long* offset, int buffersize)
{
unsigned char* buffer = (unsigned char*) malloc( buffersize * sizeof(unsigned char) );
char* clientFileName = (char*)malloc( 1024 );
/* prepare client file name */
sprintf( clientFileName, "%s%d.txt",filePath, client_id);
ssize_t readcount = 0;
if( (readcount = pread64( fildes, buffer, buffersize, *offset ) ) < 0 )
{
/* error reading file */
printf("error reading file \n");
}
else
{
*offset = *offset + readcount;
//printf("Read %ud bytes\n And offset becomes %llu\n", readcount, *offset);
int clnfildes = open( clientFileName, O_CREAT | O_TRUNC | O_WRONLY , 0777);
if( clnfildes < 0 )
{
/* error opening client file */
}
else
{
if( write( clnfildes, buffer, readcount ) != readcount )
{
/* eror writing client file */
}
else
{
close( clnfildes );
}
}
}
free( buffer );
return;
}
//fildes-源文件句柄
//偏移-要进行拆分的点
//buffersize-要拆分多少
//此函数在for循环中调用
void chunkFile(int fildes,char*filePath,int client_id,unsigned long long*offset,int buffersize)
{
unsigned char*buffer=(unsigned char*)malloc(buffersize*sizeof(unsigned char));
char*clientFileName=(char*)malloc(1024);
/*准备客户端文件名*/
sprintf(客户端文件名,“%s%d.txt”,文件路径,客户端id);
ssize_t readcount=0;
如果((readcount=pread64(fildes、buffer、buffersize、*offset))<0)
{
/*读取文件时出错*/
printf(“读取文件时出错”);
}
其他的
{
*偏移量=*偏移量+读取计数;
//printf(“读取%ud字节,偏移量变为%llu\n”,读取计数,*偏移量);
int clnfildes=open(clientFileName,O|u CREAT | O|u TRUNC | O|u WRONLY,0777);
如果(CLN文件<0)
{
/*打开客户端文件时出错*/
}
其他的
{
if(写入(CLN文件、缓冲区、读取计数)!=readcount)
{
/*eror写入客户端文件*/
}
其他的
{
关闭(clnfildes);
}
}
}
自由(缓冲);
返回;
}
我使用C++。如果其他语言可以执行得更快,我准备使用它们。rsync over SSH是否带有--partial选项? 然后您可能也不需要分割文件,因为如果传输被中断,您可以继续
文件拆分大小是预先知道的还是沿着文件中的某个标记拆分?您可以将文件存放到NFS共享设备上,客户端可以在RO模式下装载该设备。此后,客户机可以打开文件,并使用mmap()或pread()读取其切片(文件)。通过这种方式,将只需要文件的一部分传输到客户端。您可以将文件放在Web服务器的范围内,然后从客户端使用
curl
curl --range 10000-20000 http://the.server.ip/file.dat > result
将获得10000字节(从10000到20000)
如果文件高度冗余且网络速度较慢,则使用压缩可能有助于大大加快传输速度。例如执行
nc -l -p 12345 | gunzip > chunk
dd skip=10000 count=10000 if=bigfile bs=1 | gzip | nc client.ip.address 12345
在客户端上,然后执行
nc -l -p 12345 | gunzip > chunk
dd skip=10000 count=10000 if=bigfile bs=1 | gzip | nc client.ip.address 12345
在服务器上,无需创建中间文件,就可以动态地进行gzip压缩来传输节
编辑
使用网络压缩从服务器获取文件部分的单个命令是
ssh server 'dd skip=10000 count=10000 bs=1 if=bigfile | gzip' | gunzip > chunk
如果你对C++速度不满意,尝试组装,但是严重的是你的代码可能出错。您可能需要将其粘贴到此处,以便我们知道如何改进。如果我们不知道您在做什么,我们将无能为力。看到令人质疑的缓慢代码将大大有助于分析您的问题。它可以是任何东西,从一个缓慢的网络链接,到一个可怕的算法实现,两者都可以,或者完全不同的东西。如果可行,我希望进行压缩。拆分文件的大小,用于读/写的块的大小是多少?我对您的第二个解决方案感兴趣
nc
。如果我的理解是正确的,您提到的dd
命令将从bigfile
中跳过10000个字节,并将10000个1字节的块和netcat
带到客户端。是这样吗?我希望客户端拉取数据,而不是服务器推送到客户端。我有多个客户端在同一ip上运行。使用nc是否可以实现这一点?我可以让服务器让客户端知道它必须从哪个偏移量获取数据。@cppcoder:您可以使用不同的端口(我在示例中使用了12345)对于同一ip上的不同客户端,服务器可以使用ssh启动客户端命令本身。是否有任何方法可以避免服务器执行任何命令dd
,而客户端自己使用nc
从服务器获取文件?我需要这样做,因为我正在使用服务器到客户端的多播通信。我不想让服务器单独为每个客户机执行命令。