如何获取文件';在不使用fseek或stat的情况下,以C表示的s大小?
我正在为我的学校做一个项目,但我不知道如何获得文件的大小。因为我需要读取脚本并在程序中使用它,所以我需要文件的大小来使用read或fread 下面是我为获得文件大小所做的工作,但它似乎不起作用如何获取文件';在不使用fseek或stat的情况下,以C表示的s大小?,c,file,size,C,File,Size,我正在为我的学校做一个项目,但我不知道如何获得文件的大小。因为我需要读取脚本并在程序中使用它,所以我需要文件的大小来使用read或fread 下面是我为获得文件大小所做的工作,但它似乎不起作用 int my_size(int filedesc) { int size = 1; int read_output = 1; char *buffer; for (size = 1; read_output != 0 ; size++) { buffer
int my_size(int filedesc)
{
int size = 1;
int read_output = 1;
char *buffer;
for (size = 1; read_output != 0 ; size++) {
buffer = malloc((size+1)*sizeof(char*));
read_output = read(filedesc, buffer, size);
free(buffer);
}
return(size);
}
我不允许使用stat()或fseek()作为此项目的规则,也不能使用read或fread(任意大小,如100),因为给定的脚本可以是小的也可以是大的。如果您可以依赖输入作为持久文件(即驻留在存储介质上),并且在程序运行期间该文件未被修改,然后你可以预读到最后,计算其中的字节数,然后倒带 但是,除了学术练习之外,禁止通过
stat()
、fseek()
和类似方法测量大小的通常原因是输入可能不驻留在存储介质上,因此
- 首先,不要依赖于将全部内容一次性存储在内存中。取而代之的是,在读取内容时对其进行操作,在任何给定的时间只在内存中保留足够的内容
- 或者,动态适应文件大小。这方面有很多变化。例如,如果您只是将文件读入一个单片块,那么当您发现需要更多时,您可以
space和malloc()
。也可以将内容存储在链表中,根据需要分配新的列表节点realloc()
read()
都将从文件的开头开始,或者如果无法读取完整文件,则read()
可能会失败。情况也并非如此。每个read()
将从文件的当前位置开始,并在传输最后一个字节后保留文件的位置lseek()
。但是如果lseek()
可以用于此目的(请注意我之前对无法查找的文件的评论),那么它将提供一种更干净的方法来测量文件大小ssize_t count_bytes(int fd) {
ssize_t num_bytes = 0;
char buffer[2048];
ssize_t result;
do {
result = read(fd, buffer, sizeof(buffer));
if (result < 0) {
// handle error ...
}
num_bytes += result;
while (result > 0);
return num_bytes;
}
ssize\u t count\u字节(int-fd){
ssize_t num_bytes=0;
字符缓冲区[2048];
对结果进行量化;
做{
结果=读取(fd、缓冲区、sizeof(缓冲区));
如果(结果<0){
//处理错误。。。
}
num_bytes+=结果;
而(结果>0);
返回num_字节;
}
gcc-Wall-Wextra-g
with。仔细阅读您正在使用的每个函数的文档(包括您忘记了其故障的函数)
您需要使用的结果(实际读取的字节数),并且需要专门处理错误情况(当给出-1时)
在文件足够长的情况下,可能发生的情况是,在第一个循环中读取1个字节,在第二个循环中读取2个字节,在第三个循环中读取3个字节,等等(在这种情况下,您忘记计算1+2+3)
您应该累计和汇总所有的读取输出
,并且当给出的值小于大小
(这应该发生在您上次的读取
给出非零时)时,您应该处理这种情况
相反,我建议使用固定的缓冲区(常量或固定大小),并反复使用返回的字节计数(还有,处理错误和EOF条件),但要小心
请注意(中列出的)非常昂贵。根据经验,您应该使用一个几千字节的缓冲区(并仔细处理返回的字节计数,并对其进行错误测试,请参阅)。每次只运行几个字节的程序效率低下
另外,
malloc
(或realloc
)相当昂贵。将大小增加1是很难看的(因为你在每个循环中调用malloc
;在你的情况下,你甚至不需要使用malloc
)。你最好使用一些几何级数,也许newsize=4*oldsize/3+10;
(或类似).如果你不能使用fseek
,你需要实现你自己的fseek
,就像你可以做size\u t count=0;而(getchar()!=EOF)count++
-但是为什么你不能使用fseek()
plusftell()
或stat()
(大概fstat
也是不允许的)?拒绝这些内容的动机是什么?您的输入可能来自终端、管道或其他不可查找(不可重复)的设备吗?您需要保存文件内容的副本吗?@无用:按上述方法重复读取(),您将无法获得正确的大小,如read()函数将从上一次读取操作设置的偏移量中读取。您的代码是特殊的。您首先排除文件为空的可能性。您为2个字节分配空间;您读取一个字节;您释放缓冲区;您将size
按1
增加到2;您分配