【发布时间】:2018-06-24 05:52:39
【问题描述】:
我创建了一个创建文件副本的函数:读取 --> 缓冲区 --> 写入。我正在尝试多次增加缓冲区大小,看看是否会影响复制文件所需的时间(大约 50Mb)
# include <assert.h>
# include <stdio.h>
# include <stdlib.h>
# include <unistd.h>
# include <sys/types.h>
# include <sys/stat.h>
# include <sys/wait.h>
# include <string.h>
# include <fcntl.h>
# include <time.h>
// Copy the file referred to by in to out
void copy (int in, int out, char *buffer, long long taille) {
int t;
while ((t = read(in, &buffer, sizeof taille))> 0)
write (out, &buffer, t);
if (t < 0)
perror("read");
}
int main(){
clock_t timing; //to time
int buffer_size = 1;
char * buffer = NULL;
// allocating memory for the buffer
buffer = malloc(sizeof(char)*buffer_size);
// test mémoire
if (!buffer) {
perror("malloc ini");
exit(1);
}
// temporary buffer to be able to increase the siwe of the buffer
char * temp_buffer = NULL;
// opening the files
int fichier1 = open("grosfichier",O_RDONLY);
int fichier2 = open("grosfichier_copy", O_WRONLY|O_CREAT);
for (int i=0; buffer_size <= 1048576; i++){
temp_buffer = realloc(buffer, buffer_size * sizeof(char));
if(!temp_buffer) {
perror("malloc temp_buffer");
exit(1);
}
buffer = temp_buffer;
timing = clock();
copy(fichier1,fichier2, buffer, buffer_size); //recopie l'entree std dans la sortie std
timing = clock() - timing;
printf("%d, buffer size = %d, time : %ld\n", i, buffer_size, timing);
remove("grosfichier_copie");
buffer_size *= 2;
}
// free(temp_buffer);
free(buffer);
close(fichier1);
close(fichier2);
return 0;
}
代码运行并复制文件,但计时的东西不能正常工作
0, buffer size = 1, time : 6298363
1, buffer size = 2, time : 1
2, buffer size = 4, time : 1
3, buffer size = 8, time : 1
4, buffer size = 16, time : 1
5, buffer size = 32, time : 1
6, buffer size = 64, time : 1
7, buffer size = 128, time : 1
8, buffer size = 256, time : 1
9, buffer size = 512, time : 1
10, buffer size = 1024, time : 1
11, buffer size = 2048, time : 1
12, buffer size = 4096, time : 1
13, buffer size = 8192, time : 1
14, buffer size = 16384, time : 1
15, buffer size = 32768, time : 0
16, buffer size = 65536, time : 1
17, buffer size = 131072, time : 4
18, buffer size = 262144, time : 1
19, buffer size = 524288, time : 2
20, buffer size = 1048576, time : 2
[Finished in 6.5s]
- 为什么文件运行后似乎没有复制? (根据时间?)
- 我是否正确使用了免费? (我尝试在循环中移动它,但它没有运行)
- 我是否将缓冲区适当地传递给函数副本?
谢谢!
EDIT1:感谢您的所有 cmets!我已经纠正了有关在循环中打开和关闭文件、适当使用缓冲区以及建议的变量类型的主要缺陷。我得到的结果更合乎逻辑:
0, buffer size = 1, time : 8069679
1, buffer size = 2, time : 4082421
2, buffer size = 4, time : 2041673
3, buffer size = 8, time : 1020645
4, buffer size = 16, time : 514176
...
但我一直在努力正确处理 write() 错误。
Edit2:这个版本的副本好吗?
void copy (int in, int out, char *buffer, size_t taille) {
ssize_t t;
while ((t = read(in, buffer, taille))> 0){
if (write (out, buffer, t)<0){
perror("error writing");
}
}
if (t < 0)
perror("read");
}
【问题讨论】:
-
为什么你认为你可以用
%ld格式说明符打印clock_t? -
1.第一次(慢速)传递将文件加载到内核缓冲池缓存中的可能性是,其余运行不必读取它。 2. 是的。如果您使用
malloc(),则需要将其放入循环中,但如果您使用realloc(),则不需要。 3. 是的——主要是。大概,main()中的buffer_size应该是size_t,而copy()中的taille也应该是size_t。不过,您正在滥用copy()中的缓冲区。 -
'while ((t = read(in, &buffer, sizeof taille))> 0)'......'&buffer'? 'buffer' 是一个函数参数,您将其地址用作文件缓冲区......
-
您在 main 循环的第一次迭代中删除了输出文件(此后删除失败),但您没有重新打开文件描述符。这意味着您现在正在写入一个匿名文件,该文件在每次测试迭代中都在增长。您应该在写入后关闭并重新打开输出文件。此外,您不会倒带输入文件,因此第二个和后续循环不处理任何数据;循环开始时,读指针位于 EOF。这比我在第一条评论中提到的“缓存”效果重要得多。缓存是真实的;但是您的“不复制字节”问题更为严重。
-
在使用
open和O_CREAT标志时应指定permission。int fichier2 = open("grosfichier_copy", O_WRONLY|O_CREAT,0664);