C语言复制文件与缓冲区的有关问题

C语言复制文件与缓冲区的问题
直接贴代码:
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
int main(int argc, char *argv[])
{
FILE *fp1,*fp2;
unsigned char buffer[4 * 1024]; //4k
long num_read=0, num_write=0, size_all=0, size_copied=0, size_left=0;
//判断入参
if (argc != 3)
{
printf("Usage:./cp SourceFile TargetFile\n");
exit(1);
}
//打开文件
if ( (fp1=fopen(argv[1],"rb")) == NULL )
{
printf("Open \"%s\" error! %s\n",argv[1], strerror(errno));
exit(1);
}
if ((fp2=fopen(argv[2],"wb")) == NULL )
{
printf("Open \"%s\" error! %s\n",argv[2], strerror(errno));
exit(1);
}
//获取文件大小
fseek(fp1,0L,SEEK_END);
size_all=ftell(fp1);
fseek(fp1,0L,SEEK_SET);
printf("size get complete\n");
//复制
while ( (num_read = fread( buffer, sizeof(unsigned char), sizeof(buffer), fp1)) != 0 )
{
if ( (num_write = fwrite( buffer, sizeof(unsigned char), num_read, fp2)) != 0 ) 
size_copied += num_write;
else break;
}
size_left = size_all - size_copied;
//打印提示消息
printf("Size:\t%ld B\nCopied:\t%ld B\nLeft:\t%ld B\n", size_all, size_copied, size_left );
//关闭文件
fclose(fp1);
fclose(fp2);
exit(0);
}


简单的复制文件的程序,复制功能一切正常,问题处在size_copied上。当磁盘空间不足时,size_copied跟数据不正常。比如我创建了一个1M大小的磁盘,挂载到了/mnt上,复制一个4G多的文件。终端显示:
size get complete
Size: 4299161600 B
Copied: 1075547135 B
Left: 3223614465 B

复制了1G多。
怀疑跟缓冲区大小有关,但是缓冲区也不可能有1G的大小。
所以前来求教~
更想知道原因,当然有解决办法更好
Buffer 磁盘

------解决方案--------------------

xj:/home/xj/src/test# cpppp /home/xj/20121129.tar /mnt/add1/20121129.tar
size get complete
Size:   178872320 B
Copied: 92135424 B
Left:   86736896 B

xj:/home/xj/src/test# df -lh
Filesystem            Size  Used Avail Use% Mounted on
/dev/sda2              18G   11G  5.8G  65% /
/dev/sda1             289M   17M  258M   6% /boot
tmpfs                 760M     0  760M   0% /dev/shm
/dev/sdb1              99M   94M     0 100% /mnt/add1

xj:/home/xj/src/test# ls -lh /home/xj/20121129.tar