不小心格式化了视频

Accidentally formatting videos

提问人:Justin 提问时间:11/14/2023 最后编辑:Justin 更新时间:11/20/2023 访问量:98

问:

上下文

今天我正在为将来上传的视频编辑视频。我花了半天时间在CapCut上编辑。可悲的是,我为输出文件取了错误的名字,因此视频在子文件夹中分开。所以我得到的是不同文件夹中的 24 个同名视频。然后我想我可以尝试制作一个代码,将所有文件从子文件夹移动到正确的文件夹。

发生了什么事

所以我想出了这个代码,它使所有文件都消失了。莫斯蒂试图咨询人工智能。接下来的事情非常糟糕,我希望我们能以某种方式耐心地获得正确的输出。所以我认为这段代码只会移动文件。不幸的是,所有文件都被格式化为各种文件。.ini、.crc、.meta、.string、.model、.jpg、.ini、.extra、.png、.html、.js、.css、.meta、.lua。

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

void moveFiles(const char *sourceDir, const char *destDir) {
    DIR *dir = opendir(sourceDir);
    if (dir == NULL) {
        perror("Error opening source directory");
        return;
    }

    struct dirent *entry;
    while ((entry = readdir(dir)) != NULL) {
        if (strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0) {
            char srcPath[256];
            snprintf(srcPath, sizeof(srcPath), "%s/%s", sourceDir, entry->d_name);

            struct stat fileStat;
            if (stat(srcPath, &fileStat) == 0) {
                if (S_ISREG(fileStat.st_mode)) {
                    char destPath[256];
                    snprintf(destPath, sizeof(destPath), "%s/%s", destDir, entry->d_name);
                    if (rename(srcPath, destPath) != 0) {
                        perror("Error moving file");
                    }
                } else if (S_ISDIR(fileStat.st_mode)) {
                    char subdir[256];
                    snprintf(subdir, sizeof(subdir), "%s/%s", sourceDir, entry->d_name);
                    moveFiles(subdir, destDir);
                }
            }
        }
    }

    closedir(dir);
}

int main() {
    // Get the user's home directory
    const char *homedir;
    struct passwd *pw = getpwuid(geteuid());
    if (pw != NULL) {
        homedir = pw->pw_dir;
    } else {
        perror("Error getting home directory");
        return 1;
    }

    // Append "Movies" directory to the home directory path
    char moviesDir[256];  // Assuming the directory path won't exceed 256 characters
    snprintf(moviesDir, sizeof(moviesDir), "%s/Movies", homedir);

    // Move files from subdirectories to the "Movies" directory
    moveFiles(moviesDir, moviesDir);

    printf("Files from subdirectories moved to the 'Movies' directory.\n");

    return 0;
}

我的视频不见了,还是有办法找回它们?

更新

当我想从搜索浏览器(例如YouTube)打开文件夹时,它会以原始格式保留所有视频,我可以上传,因为什么也没发生。从浏览器查看文件是否对以 .mov 格式查看这些文件有任何影响?

C 视频 格式 输出

评论

0赞 chux - Reinstate Monica 11/15/2023
由于可能会失败(缓冲区不够大),为什么代码不检查返回值?此外,我建议失败导致操作停止,而不是继续。snprintf()snprintf()
0赞 chux - Reinstate Monica 11/15/2023
提示:不要在每个级别创建一个 256 缓冲区,而是在顶部创建一个 4k 缓冲区,并将其和使用的长度传递到 .moveFiles()
1赞 chux - Reinstate Monica 11/15/2023
moveFiles(moviesDir, moviesDir);--> 真的打算将文件从 A 移动到 A 吗?
0赞 Craig Estey 11/15/2023
很抱歉,不幸的是,某些文件可能会丢失。所以我得到的是不同文件夹中的 24 个同名视频对我来说,这表示您的原始层次结构是(例如)并且您的程序会将这两个文件移动到 ,因此其中一个将丢失。我编写了一个脚本,该脚本在各个子目录中生成具有相同名称的文件的随机层次结构。我在上面运行了你的程序。我从 113 个文件开始,但在您的程序运行后,我只剩下 49 个文件Movies/dirX/fileAMovies/dirY/fileAMovies/fileA
0赞 Craig Estey 11/15/2023
您的程序确实将所有平面文件从任何和所有子目录移动到顶级目录中(它将保留 [空] 子目录)。因此,AFAICT,您留下的任何文件都直接位于 .在 POSIX/linux 下,可能什么也做不了。但是,在您的程序中,名称限制为 256 个字符。这是 Windows 限制。那么,您使用的是 Windows 吗?他们为每个文件添加了某种文件历史记录,以代替图像备份 elevenforum.com/t/......Movies

答:

0赞 Justin 11/27/2023 #1

简单的答案

只需尝试在不同的子目录中编写代码即可。您会发现该程序可以完美地满足您的需求。发生的事情是,您的视频被移动了,但也被破坏成不同的格式。创建的文件列表太长了,以至于无法跟踪文件夹中的内容。

保证视频正常:

由于您提到通过 YouTube 等浏览器访问时能够以原始格式查看视频,这表明视频没有丢失或损坏。这是一个积极的信号。

尝试使用不同的子目录:

尝试从不同的子目录中移动文件以确保该过程按预期工作可能会有所帮助。这涉及调整代码中的源子目录和目标目录路径并重新运行它。

请尝试以下解决方案:

void moveFiles(const char *sourceDir, const char *destDir) {
    DIR *dir = opendir(sourceDir);
    if (dir == NULL) {
        perror("Error opening source directory");
        return;
    }

    struct dirent *entry;
    while ((entry = readdir(dir)) != NULL) {
        if (strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0) {
            char srcPath[256];
            snprintf(srcPath, sizeof(srcPath), "%s/%s", sourceDir, entry->d_name);

            struct stat fileStat;
            if (stat(srcPath, &fileStat) == 0) {
                if (S_ISREG(fileStat.st_mode)) {
                    if (strstr(entry->d_name, ".str") != NULL) {
                        // Skip .str files and remove them instead of moving
                        if (remove(srcPath) != 0) {
                            perror("Error removing .str file");
                        }
                    } else {
                        char destPath[256];
                        snprintf(destPath, sizeof(destPath), "%s/%s", destDir, entry->d_name);
                        if (rename(srcPath, destPath) != 0) {
                            perror("Error moving file");
                        }
                    }
                } else if (S_ISDIR(fileStat.st_mode)) {
                    moveFiles(srcPath, destDir);
                }
            }
        }
    }

    closedir(dir);
}

在主要功能中更容易。

    const char *sourceSubDir = "/Path/to/subdirectories"; // Source subdirectory
    const char *destDir = "/Path/to/destination/directory"; // Destination directory
    
    moveFiles(sourceSubDir, destDir);