it-swarm.dev

كيفية التحقق من وجود ملف قبل إنشاء ملف جديد

أرغب في إدخال بعض المحتويات في ملف ، لكن أود التحقق أولاً من وجود ملف يحمل الاسم الذي أرغب في إنشائه. إذا كان الأمر كذلك ، فأنا لا أريد إنشاء أي ملف ، حتى لو كان الملف فارغًا.

محاولتي

bool CreateFile(char name[], char content[]){
     std::ofstream file(name);
     if(file){
         std::cout << "This account already exists" << std::endl;
        return false;
     }
     file << content;
     file.close();
     return true;
}

هل هناك أي طريقة لفعل ما أريد؟

27
Lion King

على افتراض أنه لا بأس من أن العملية ليست ذرية ، يمكنك القيام بما يلي:

if (std::ifstream(name))
{
     std::cout << "File already exists" << std::endl;
     return false;
}
std::ofstream file(name);
if (!file)
{
     std::cout << "File could not be created" << std::endl;
     return false;
}
... 

لاحظ أن هذا لا يعمل إذا قمت بتشغيل عدة سلاسل رسائل تحاول إنشاء نفس الملف ، وبالتأكيد لن تمنع العملية الثانية من "التداخل" مع إنشاء الملف لأنك TOCTUI المشاكل. [نحن نتحقق أولاً من وجود الملف ، ثم ننشئه - لكن شخصًا آخر كان بإمكانه إنشاءه بين الاختيار والإعداد - إذا كان هذا أمرًا بالغ الأهمية ، فستحتاج إلى القيام بشيء آخر ، وهو أمر غير قابل للنقل].

هناك مشكلة أخرى إذا كان لديك أذونات مثل الملف غير قابل للقراءة (لذلك لا يمكننا فتحه للقراءة) ولكن قابل للكتابة ، فإنه سيتم الكتابة فوق الملف.

في معظم الحالات ، لا يهم أي من هذه الأشياء ، لأن كل ما يهمك هو إخبار شخص ما "لديك بالفعل ملفًا كهذا" (أو شيء من هذا القبيل) في نهج "أفضل جهد".

27
Mats Petersson

يمكنك أيضا استخدام دفعة.

 boost::filesystem::exists( filename );

كان يعمل للملفات والمجلدات.

وسيكون لديك تطبيق قريب من شيء جاهز لـ C++ 14 والذي يجب أن يكون نظام الملفات جزءًا من STL (انظر هنا ).

13
alexbuisson

محاولة

ifstream my_file("test.txt");
if (my_file)
{
 // do stuff
}

من: كيفية التحقق من وجود ملف وقراءته في C++؟

أو يمكنك استخدام وظائف دفعة.

8
CBIII

جرب هذا (تم نسخه من إريك جاريسون: https://stackoverflow.com/a/3071528/5755 )

#include <sys/stat.h>

bool FileExists(char* filename) 
{
    struct stat fileInfo;
    return stat(filename, &fileInfo) == 0;
}

stat تُرجع 0 في حالة وجود الملف و -1 إن لم يكن.

7
dumbledad

اعتبارًا من الإصدار C++ 17:

if (std::filesystem::exists(pathname)) {
   ...
6
James Hirschorn

نظرت حولي قليلاً ، والشيء الوحيد الذي أجده هو استخدام مكالمة النظام open. إنها الوظيفة الوحيدة التي وجدتها والتي تتيح لك إنشاء ملف بطريقة ستفشل إذا كان موجودًا بالفعل

#include <fcntl.h>
#include <errno.h>

int f=open(filename, O_WRONLY | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
if (f < 0) {
  /* file exists or otherwise uncreatable
     you might want to check errno*/
}else {
  /* File is open to writing */
}

لاحظ أنه يجب عليك منح أذونات لأنك تقوم بإنشاء ملف.

هذا يزيل أيضا أي شروط السباق قد يكون هناك

2
rabensky

C++ 17 ، عبر النظام الأساسي: باستخدام std::filesystem::exists و std::filesystem::is_regular_file .

#include <filesystem> // C++17
#include <fstream>
#include <iostream>
namespace fs = std::filesystem;

bool CreateFile(const fs::path& filePath, const std::string& content)
{
    try
    {
        if (fs::exists(filePath))
        {
            std::cout << filePath << " already exists.";
            return false;
        }
        if (!fs::is_regular_file(filePath))
        {
            std::cout << filePath << " is not a regular file.";
            return false;
        }
    }
    catch (std::exception& e)
    {
        std::cerr << __func__ << ": An error occurred: " << e.what();
        return false;
    }
    std::ofstream file(filePath);
    file << content;
    return true;
}
int main()
{
    if (CreateFile("path/to/the/file.ext", "Content of the file"))
    {
        // Your business logic.
    }
}
0
Roi Danton

رأيت للتو هذا الاختبار:

bool getFileExists(const TCHAR *file)
{ 
  return (GetFileAttributes(file) != 0xFFFFFFFF);
}
0
Racky