【问题标题】:stat() returns errorstat() 返回错误
【发布时间】:2012-05-03 09:23:01
【问题描述】:

我必须知道文件夹中某些文件的修改日期。它有效,但不适用于所有类型的文件。 例如,它适用于 .c、.txt,但不适用于其他类型,如 .mp4、.jpg 和 .mp3(我正在创建的应用程序通常必须适用于多媒体文件)。它打印“无法显示时间。”,所以我想问题出在 stat() 上。谢谢。

这是代码:

#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#include <string.h>
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>

char parola[12]="", hash[32]="", esadecimale[1000]="", system3[100]="./md5 ";
int i, len, len2;
int bytes;
char cwd[1024];

int main(void)
{
char t[100] = "";
struct stat b;
DIR *dp;
char destinationFolder[100] = "/Users/mattiazeni/Desktop/Prova/"; //Me la passa da sopra
struct dirent *dir_p;
dp = opendir(destinationFolder);
if ( dp == NULL ) exit(1);

len = strlen(destinationFolder);

for (i=0;i<len;i++) {
    system3[i+6]=destinationFolder[i];
}

while( ( dir_p = readdir(dp) ) != NULL ) {
    if (dir_p -> d_name[0] != '.') {
        //printf("%s\n", dir_p -> d_name);
        len2 = strlen(dir_p -> d_name);
        for (i=0;i<len2;i++) {
            if (dir_p -> d_name[i] == ' '){ //Mi serve per correggere i nomi dei file con spazi
                system3[i+len+6]='\\';   
            }
            else system3[i+len+6]=dir_p -> d_name[i];
        }
        system(system3); //Passa il valore a md5 che calcola l'hash e lo stampa nel file che ci serve insieme al persorso/nome del file

        FILE *fp;
        if((fp=fopen("userDatabase.txt", "ab"))==NULL) {
            printf("Error while opening the file..\n");
            fclose (fp);
        }
        else {
            if (!stat(dir_p -> d_name, &b)) {
            strftime(t, 100, "%d/%m/%Y %H:%M:%S", localtime( &b.st_mtime));         //C'è ancora qualche errore!!
            fprintf(fp, "%s", t);           
            }
            else {
                perror(0);
                fprintf(fp, "error");
            }
            fprintf(fp, " initialized");
            fprintf(fp, "\n");
        }
        fclose (fp);
        for (i=len+6;i<len+6+len2;i++) {
            system3[i]=' ';
        }
    }
}   
closedir(dp);
return 0;
}

【问题讨论】:

  • 使用 perror 而不是“无法显示时间” printf 来了解您遇到的错误。

标签: c stat strftime localtime


【解决方案1】:

使用perror()。你也不应该使用st_mtime吗?

统计:
       成功时,返回零。
       出错时返回 -1,并适当设置 errno

99% 确定这是因为 dir_p -&gt; d_name 不存在,而这又可能是由于本地化问题。

你可以这样做:

fprintf(stderr, 
        "Unable to stat %s\n",
        dir_p->d_name); 
perror(0);

还有;如果您正在检查文件状态,不应该是-&gt;f_name 而不是-&gt;d_name? - (除非你使用 d_name 作为文件名。)

您的fclose(fp) 在您的fp == NULL 支票之外。由于您不返回或以其他方式中止流程,因此如果 fopen 失败,您将面临 SIGSEGV 风险。


编辑:你对这样的事情有什么好处?

#include <unistd.h>

char cwd[1024];

...  


} else {
    fprintf(stderr,
            "Unable to stat '%s'\n",
            dir_p->d_name);
    perror(0);

    if (getcwd(cwd, sizeof(cwd)) == NULL) {
        perror("getcwd() error");
    } else {
        fprintf(stderr,
                "in directory  '%s'\n",
                cwd);
    }
} 

编辑2:

首先;我说getcwd() != NULL 应该是==。硒变化。 (对我不好。)

代码中的问题。 (还有一些)但关于 stat - 您使用来自 readdir 的 d_name。这是唯一文件名;不是目录+文件名。因此;你得到即:

stat(dir_p->d_name, ...)

变成即:

stat("file.mp4", ...)

最简单的快速修复(虽然脏)是:

/* you need to terminate the system string after your for loop */
system3[i + len + 6] = '\0';

system(system3);

if (!stat(system3 + 6, &b)) {

【讨论】:

  • 感谢您的回复。我使用 dir_p -> d_name 因为我扫描目录以了解其中有哪些文件,然后对于每个文件我想知道修改日期。随着 perror 我得到“没有这样的文件或目录”。但我不明白为什么,文件就在那里。另外因为在这些文件上我计算了 md5 哈希值,而且效果很好,问题只出在日期上。
  • @phcaze:dir_p-&gt;d_name 打印成什么?还;如果您对其进行一些更改,您可以检查当前工作目录。使用类似上面的新代码。它打印什么?
  • dir_p->d_name 使用文件名 /Users/user/Desktop/file.mp4 打印路径。使用您的代码,它会在屏幕上打印“/Users/user/Desktop/file.mp4 getcwd() error: Undefined error: 0”。
  • @phcaze 更新了示例代码。另一个注意事项;你说你统计目录,但/Users/user/Desktop/file.mp4 看起来像一个文件。你有更完整的样本要发布吗?哪些可以编译以重现您的体验?
  • @phcaze:还请注意,您的转义序列失败(您使用 \\ 填充但不添加空格)。您对数组的长度有一些限制。 IE。如果 len 或 len2 > 93。更糟糕的是,在使用后通过设置为 ' ' 来“消隐”。如果您有一个足够大的数组,只需在您希望它结束​​的地方添加一个 '\0' - 当数组被解释为 C 字符串时,不会读取超出此范围的旧数据。
【解决方案2】:

您应该使用 stat() 的完整路径名。 Stat 不知道您对哪个目录感兴趣。

... 
char  bigbuff[PATH_MAX];

sprintf( bigbuff, "%s/%s", destinationFolder, dir_p->d_name);

rc = stat (bigbuff, &b);
...

【讨论】:

  • 是的,这就是问题所在! :) 谢谢。但是为什么它只给我一些文件的错误呢?
【解决方案3】:

这是最终的工作代码,用于扫描目录中的文件,并将它们打印在带有修改日期的 txt 输出文件中:

#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#include <string.h>
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>

char system3[6]="./md5 ";

int main(void)
{
char t[100] = "";
char bigbuff[200];
struct stat b;
char destinationFolder[100] = "/Users/mattiazeni/Desktop/Prova"; //Me la passa da sopra
DIR *dp;
struct dirent *dir_p;
dp = opendir(destinationFolder);
if ( dp == NULL ) exit(1);
while( ( dir_p = readdir(dp) ) != NULL ) {
    if (dir_p -> d_name[0] != '.') {
        sprintf( bigbuff, "%s%s/%s",system3, destinationFolder, dir_p->d_name);
        system(bigbuff); 

        FILE *fp;
        if((fp=fopen("userDatabase.txt", "ab"))==NULL) {
            printf("Error while opening the file..\n");
            fclose (fp);
        }
        else {
            sprintf( bigbuff, "%s/%s", destinationFolder, dir_p->d_name);
            if (!stat(bigbuff, &b)) {
            strftime(t, 100, "%d/%m/%Y %H:%M:%S", localtime( &b.st_mtime));         //C'è ancora qualche errore!!
            fprintf(fp, "%s", t);           
            }
            else {
                perror(0);
                fprintf(fp, "error");
            }
            fprintf(fp, "\n");
        }
        fclose (fp);
    }
}   
closedir(dp);
return 0;
}

感谢大家的帮助!

【讨论】:

    猜你喜欢
    • 2016-04-11
    • 1970-01-01
    • 2010-11-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-05
    相关资源
    最近更新 更多