วิธีที่เร็วที่สุดในการตรวจสอบว่าไฟล์มีอยู่โดยใช้มาตรฐาน C ++ / C ++ 11 / C หรือไม่


453

ฉันต้องการค้นหาวิธีที่เร็วที่สุดในการตรวจสอบว่าไฟล์มีอยู่ในมาตรฐาน C ++ 11, C ++ หรือ C ฉันมีไฟล์หลายพันไฟล์และก่อนที่จะทำอะไรกับพวกเขาฉันต้องตรวจสอบว่ามีอยู่ทั้งหมดหรือไม่ ฉันสามารถเขียนอะไรได้บ้าง/* SOMETHING */ในฟังก์ชั่นต่อไปนี้

inline bool exist(const std::string& name)
{
    /* SOMETHING */
}

2
boost::filesystemstat()ดูเหมือนว่าจะใช้ (สมมติจากเอกสาร) ฉันไม่คิดว่าคุณจะทำได้เร็วกว่านี้สำหรับการโทร FS วิธีสร้างสิ่งที่คุณกำลังทำอย่างรวดเร็วคือ "หลีกเลี่ยงการดูไฟล์หลายพันไฟล์"
millimoose

16
คำถามของTOCTOU : คุณจะรู้ได้อย่างไรว่าไฟล์ไม่ได้ถูกยกเลิกการเชื่อมโยงระหว่างการตรวจสอบที่มีอยู่ () และ"การทำอะไรบางอย่างกับมัน" ?
pilcrow

7
@pilcrow จุดที่ดี แต่มีแอพพลิเคชั่นที่ค่อนข้างหลากหลายซึ่งไม่ต้องการความถูกต้องมากนัก เช่นgit pushอาจไม่รบกวนเพื่อให้แน่ใจว่าคุณไม่ได้สัมผัสต้นไม้ทำงานหลังจากการตรวจสอบสกปรกครั้งแรก
millimoose

9
'ฉันไม่สามารถนึกถึงการใช้งาน C / C ++ ที่ไม่มี' - Windows ไม่ได้จัดเตรียมสภาพแวดล้อม POSIX
Jim Balter

3
มีความเป็นไปได้ที่ซ้ำกันของstd :: ofstream ตรวจสอบว่ามีไฟล์อยู่ก่อนเขียนหรือไม่
MD XF

คำตอบ:


778

ฉันรวมโปรแกรมทดสอบที่ใช้แต่ละวิธี 100,000 ครั้งครึ่งหนึ่งบนไฟล์ที่มีอยู่และอีกครึ่งหนึ่งในไฟล์ที่ไม่ได้

#include <sys/stat.h>
#include <unistd.h>
#include <string>
#include <fstream>

inline bool exists_test0 (const std::string& name) {
    ifstream f(name.c_str());
    return f.good();
}

inline bool exists_test1 (const std::string& name) {
    if (FILE *file = fopen(name.c_str(), "r")) {
        fclose(file);
        return true;
    } else {
        return false;
    }   
}

inline bool exists_test2 (const std::string& name) {
    return ( access( name.c_str(), F_OK ) != -1 );
}

inline bool exists_test3 (const std::string& name) {
  struct stat buffer;   
  return (stat (name.c_str(), &buffer) == 0); 
}

ผลลัพธ์สำหรับเวลาทั้งหมดในการเรียกใช้ 100,000 การโทรโดยเฉลี่ยมากกว่า 5 ครั้ง

Method exists_test0 (ifstream): **0.485s**
Method exists_test1 (FILE fopen): **0.302s**
Method exists_test2 (posix access()): **0.202s**
Method exists_test3 (posix stat()): **0.134s**

stat()ฟังก์ชั่นที่ให้ประสิทธิภาพที่ดีที่สุดในระบบของฉัน (ลินุกซ์คอมไพล์ด้วยg++) ที่มีมาตรฐานfopenการโทรเป็นทางออกที่ดีที่สุดของคุณถ้าคุณสำหรับบางคนปฏิเสธเหตุผลที่จะใช้ฟังก์ชั่น POSIX


31
ไม่มีวิธีการใด ๆ ข้างต้นที่ตรวจสอบว่ามีอยู่จริง แต่ค่อนข้างจะเข้าถึงได้ง่าย แม้ว่าฉันไม่รู้วิธี C หรือ C ++ มาตรฐานเดียวในการตรวจสอบการมีอยู่
IIsspectable

10
stat()ดูเหมือนว่าจะตรวจสอบการมีอยู่
el.pescado

105
ทุกคนที่ใช้สิ่งนี้จำเป็นต้องจำไว้ว่าให้ #include <sys / stat.h> ไม่เช่นนั้นจะพยายามใช้สถิติที่ไม่ถูกต้อง
Katianie

23
ฉันจินตนาการถึงวิธี ifstream คุณไม่ต้องการf.close()เนื่องจาก f ออกนอกขอบเขตที่ส่วนท้ายของฟังก์ชัน ดังนั้นreturn f.good()สามารถแทนที่ifบล็อกได้หรือไม่
ilent2

11
นอกจากนี้คุณยังสามารถใช้ / ทดสอบen.cppreference.com/w/cpp/experimental/fs/existsจากมาตรฐานที่กำลังจะมาถึง
zahir

153

หมายเหตุ: ใน C ++ 14 และทันทีที่ระบบไฟล์ TSเสร็จสิ้นและปรับใช้โซลูชันจะใช้:

std::experimental::filesystem::exists("helloworld.txt");

และตั้งแต่ C ++ 17 เท่านั้น:

std::filesystem::exists("helloworld.txt");

5
มีอยู่แล้วในBoost.Filesystem
TemplateRex

1
ใน MS Visual Studio 2013 ฟังก์ชันนี้มีให้บริการภายใต้std::tr2::sys::exists("helloworld.txt");
Constantin

3
ฉันหวังว่ามันจะไม่เป็นstd::existsเช่นนั้นจะค่อนข้างสับสน (คิดว่า: มีอยู่ในคอนเทนเนอร์ STL เหมือนชุด)
einpoklum

3
นอกจากนี้ใน Visual Studio 2015:#include <experimental/filesystem> bool file_exists(std::string fn) { std::experimental::filesystem::exists("helloworld.txt"); }
Orwellophile

1
อย่าลืม#include <experimental/filesystem>
Mohammed Noureldin

112

ฉันใช้รหัสชิ้นนี้มันใช้งานได้ดีกับฉันจนถึงตอนนี้ สิ่งนี้ไม่ได้ใช้คุณสมบัติแฟนซีมากมายของ C ++:

bool is_file_exist(const char *fileName)
{
    std::ifstream infile(fileName);
    return infile.good();
}

8
อย่างไรก็ตามมันอาจล้มเหลวหากไฟล์ถูกล็อคโดยโปรแกรมอื่นหรือหากไม่มีการเข้าถึงไฟล์
Jet

2
คุณจำเป็นต้องปิดสตรีมหรือไม่
Mo0gles

29
@ Mo0gles: ผู้ifstreamทำลายจะถูกเรียกเมื่อออกมาis_file_existและจะปิดกระแส
ไอแซค

2
ตั้งแต่ C ++ 11 คุณสามารถทำได้ในหนึ่งบรรทัดโดยใช้โอเปอเรเตอร์บูล: en.cppreference.com/w/cpp/io/basic_ios/operator_bool
Mugen

6
@Orwellophilereturn std::ifstream(fileName);
emlai

27

ขึ้นอยู่กับว่าไฟล์อยู่ที่ไหน ตัวอย่างเช่นหากพวกเขาทั้งหมดควรจะอยู่ในไดเรกทอรีเดียวกันคุณสามารถอ่านรายการไดเรกทอรีทั้งหมดลงในตารางแฮชแล้วตรวจสอบชื่อทั้งหมดกับตารางแฮช สิ่งนี้อาจเร็วกว่าในบางระบบมากกว่าการตรวจสอบแต่ละไฟล์ วิธีที่เร็วที่สุดในการตรวจสอบแต่ละไฟล์นั้นขึ้นอยู่กับระบบของคุณ ... ถ้าคุณกำลังเขียน ANSI C วิธีที่เร็วที่สุดก็คือfopenเพราะมันเป็นวิธีเดียว (ไฟล์อาจมีอยู่ แต่ไม่สามารถเปิดได้ แต่คุณอาจต้องการเปิดได้จริงๆถ้าคุณ จำเป็นต้อง "ทำอะไรกับมัน") C ++, POSIX, Windows ทั้งหมดมีตัวเลือกเพิ่มเติม

ในขณะที่ฉันอยู่ที่นี่ขอให้ฉันชี้ปัญหาบางอย่างกับคำถามของคุณ คุณบอกว่าคุณต้องการวิธีที่เร็วที่สุดและคุณมีไฟล์นับพัน แต่คุณขอรหัสเพื่อให้ฟังก์ชั่นทดสอบไฟล์เดียว (และฟังก์ชันนั้นใช้ได้เฉพาะใน C ++ ไม่ใช่ C) นี้ขัดแย้งกับความต้องการของคุณโดยการทำให้สมมติฐานเกี่ยวกับการแก้ปัญหา ... กรณีของปัญหา XY นอกจากนี้คุณยังพูดว่า "ในมาตรฐาน c ++ 11 (หรือ) c ++ (หรือ) c" ... ซึ่งแตกต่างกันทั้งหมดและสิ่งนี้ก็ไม่สอดคล้องกับความต้องการของคุณสำหรับความเร็ว ... โซลูชันที่เร็วที่สุดจะเกี่ยวข้องกับการปรับแต่งรหัสให้เหมาะกับ ระบบเป้าหมาย ความไม่สอดคล้องกันในคำถามถูกเน้นด้วยข้อเท็จจริงที่ว่าคุณยอมรับคำตอบที่ให้วิธีการแก้ปัญหาที่ขึ้นอยู่กับระบบและไม่ใช่ C หรือ C ++ มาตรฐาน


25

สำหรับผู้ที่ชอบเพิ่ม:

 boost::filesystem::exists(fileName)

5
Boost มักจะช้ามาก
Serge Rogatch

4
สำหรับแอปพลิเคชันส่วนใหญ่การตรวจสอบไฟล์ที่มีอยู่นั้นไม่ได้มีความสำคัญอย่างยิ่งยวด
anhoppe

29
ไม่ใช่ทุกแง่มุมของแอปพลิเคชั่นประสิทธิภาพสูงที่ต้องมีการปรับให้เหมาะสม ตัวอย่างเช่นการอ่านบรรทัดคำสั่งหรือไฟล์กำหนดค่าอาจมีความซับซ้อนและอาจไม่ต้องการความเร็วแม้ว่าแอปพลิเคชันเองอาจต้องการประสิทธิภาพการทำงานของ C ++ การหลีกเลี่ยงการเพิ่มประสิทธิภาพในกรณีเช่นนี้ถือเป็นการสร้างใหม่ของล้อซึ่งสูงในรายการต่อต้านรูปแบบ
evoskuil

5
@SergeRogatch boost :: ระบบแฟ้ม :: มีอยู่ไม่ช้ามาก ดูผลลัพธ์มาตรฐานของฉันสำหรับข้อมูลรายละเอียด
Hungptit

3
"Boost มักจะช้ามาก" - นี่เป็นเท็จและยังไม่ชัดเจนว่าขอบเขตของการอ้างสิทธิ์คืออะไร ... Boost มีแพ็คเกจจำนวนมากโดยผู้เขียนที่แตกต่างกัน แต่ได้รับการตรวจสอบเพื่อคุณภาพสูง "สำหรับแอพพลิเคชั่นส่วนใหญ่การตรวจสอบไฟล์ที่มีอยู่นั้นไม่ได้มีความสำคัญต่อประสิทธิภาพ" - OP ต้องการการตรวจสอบความเร็วโดยเฉพาะเนื่องจากการตรวจสอบไฟล์จำนวนมาก "ถ้าประสิทธิภาพไม่สำคัญแสดงว่าไม่มีจุดในการใช้ C ++" - ข้อคิดเห็นอื่นที่ผิดพลาด (และหัวข้อปิด) ซอฟต์แวร์ส่วนใหญ่เขียนในร้านค้าและเป็นส่วนหนึ่งของระบบที่ใช้ในการเลือกภาษา
Jim Balter

23

หากไม่ใช้ห้องสมุดอื่นฉันชอบใช้ข้อมูลโค้ดต่อไปนี้:

#ifdef _WIN32
   #include <io.h> 
   #define access    _access_s
#else
   #include <unistd.h>
#endif

bool FileExists( const std::string &Filename )
{
    return access( Filename.c_str(), 0 ) == 0;
}

สิ่งนี้ทำงานข้ามแพลตฟอร์มสำหรับระบบ Windows และ POSIX


ใช้งานกับ Mac ได้หรือไม่ ฉันไม่มี mac แต่ฉันคาดหวังว่า mac จะสามารถรวมได้unistd.hเช่นกัน อาจ#ifdefจะเป็นหน้าต่างแรกที่เฉพาะเจาะจง?
matth

5
Mac OSX เป็นไปตาม POSIX
schaiba

20

เหมือนกับที่ PherricOxide แนะนำ แต่เป็น C

#include <sys/stat.h>
int exist(const char *name)
{
  struct stat   buffer;
  return (stat (name, &buffer) == 0);
}

1
.c_str () เป็นฟังก์ชัน C ++ ฉันไม่รู้ C ++ ดังนั้นฉันจึงโพสต์รายการเทียบเท่า C
Ramon La Pietra

10
inline bool exist(const std::string& name)
{
    ifstream file(name);
    if(!file)            // If the file was not found, then file is 0, i.e. !file=1 or true.
        return false;    // The file was not found.
    else                 // If the file was found, then file is non-0.
        return true;     // The file was found.
}

19
หากคุณกำลังจะทำเช่นนั้นจริงๆเพียงแค่ "ส่งคืนไฟล์ (บูล)" แทนที่จะใช้สาขา if / else
Nik Haldimann

อย่าลืมปิดไฟล์ในกรณีที่เกิดกรณีจริง นั่นเป็นประเภทของหน่วยความจำรั่วถ้าคุณปล่อยให้ไฟล์เปิดตลอดทั้งรันไทม์ของโปรแกรมไม่ต้องพูดถึงมันอาจล็อคไฟล์ของคุณเพื่อที่คุณจะไม่สามารถอ่านได้หลังจากรู้ว่ามันมีอยู่แล้ว .. เพิ่ม: file.close () ไปที่อื่น
Bill Moore

2
ในความคิดที่สองบางทีคุณไม่จำเป็นต้องปิดมันอย่างชัดเจน ... ฉันลืมว่า ifstream เป็น RAII (การจัดหาทรัพยากรคือการเริ่มต้น) ... และจะล้างตัวเองเมื่อมันพ้นขอบเขตจากผู้ทำลายล้าง ... อะไร ผมสามารถพูดได้ ... ฉันจะได้รับล้างสมองโดยภาษาที่เก็บขยะวันนี้ ...
บิลมัวร์

@BillMoore ความคิดเห็นที่สองของคุณถูกต้อง; close()ไม่จำเป็นต้องแสดงความคิดเห็นอื่น ๆ ในหน้านี้อีก
Keith M

สิ่งนี้ตรวจสอบการช่วยสำหรับการเข้าถึงไม่ใช่การมีอยู่จริง ตัวอย่างเช่นหากไฟล์มีอยู่ แต่ไม่สามารถเข้าถึงได้เนื่องจากสิทธิ์การเข้าถึงไฟล์นั้นจะส่งคืนเท็จโดยไม่ได้ตั้งใจอ้างว่าไฟล์นั้นไม่มีอยู่
SasQ

7

อีก 3 ตัวเลือกภายใต้ windows:

1

inline bool exist(const std::string& name)
{
    OFSTRUCT of_struct;
    return OpenFile(name.c_str(), &of_struct, OF_EXIST) != INVALID_HANDLE_VALUE && of_struct.nErrCode == 0;
}

2

inline bool exist(const std::string& name)
{
    HANDLE hFile = CreateFile(name.c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    if (hFile != NULL && hFile != INVALID_HANDLE)
    {
         CloseFile(hFile);
         return true;
    }
    return false;
}

3

inline bool exist(const std::string& name)
{
    return GetFileAttributes(name.c_str()) != INVALID_FILE_ATTRIBUTES;
}

OpenFile เป็น ANSI เท่านั้นและจำกัด อยู่ที่ 128 ตัวอักษร
David Bremner

5
GetFileAttributesรุ่นนั้นเป็นวิธีที่ยอมรับที่จะทำมันใน Windows
เฟลิกซ์ดอมเบ

ฉันรู้ว่ามันเก่า แต่จะเกิดอะไรขึ้นในกรณีที่ 3 เมื่อผู้ใช้มีความสามารถในการอ่านไฟล์ แต่ไม่ได้รับอนุญาตให้อ่านคุณสมบัติของไฟล์?
Quest

6

bool b = std::ifstream('filename').good();นอกจากนี้คุณยังอาจจะทำ หากไม่มีคำสั่งสาขา (เช่นถ้า) จะต้องทำงานได้เร็วขึ้นเนื่องจากต้องเรียกหลายพันครั้ง


ตามคำตอบที่ยอมรับแสดงว่านี่เป็นเรื่องจริง คอมไพเลอร์ที่จริงจังอาจจะปล่อยรหัสเดียวกันไม่ว่าคุณจะใส่ในifหรือไม่ เมื่อเปรียบเทียบกับตัวแปร C ธรรมดา ๆ การสร้างวัตถุ ifstream (แม้ว่าในสแต็ก) จะมีค่าใช้จ่ายเพิ่มเติม
Minexew

6

หากคุณต้องการแยกความแตกต่างระหว่างไฟล์และไดเรกทอรีให้พิจารณาสิ่งต่อไปนี้ซึ่งทั้งสองใช้สถิติที่เป็นเครื่องมือมาตรฐานที่เร็วที่สุดตามที่แสดงโดย PherricOxide:

#include <sys/stat.h>
int FileExists(char *path)
{
    struct stat fileStat; 
    if ( stat(path, &fileStat) )
    {
        return 0;
    }
    if ( !S_ISREG(fileStat.st_mode) )
    {
        return 0;
    }
    return 1;
}

int DirExists(char *path)
{
    struct stat fileStat;
    if ( stat(path, &fileStat) )
    {
        return 0;
    }
    if ( !S_ISDIR(fileStat.st_mode) )
    {
        return 0;
    }
    return 1;
}

4

ฉันต้องการฟังก์ชั่นเร็วที่สามารถตรวจสอบว่ามีไฟล์อยู่หรือไม่และคำตอบของ PherricOxide นั้นเกือบจะเป็นสิ่งที่ฉันต้องการยกเว้นมันไม่ได้เปรียบเทียบประสิทธิภาพของ boost :: filesystem :: มีอยู่และฟังก์ชั่นเปิด จากผลการวัดประสิทธิภาพเราจะเห็นว่า:

  • การใช้ฟังก์ชั่นสถิติเป็นวิธีที่เร็วที่สุดในการตรวจสอบว่ามีไฟล์อยู่หรือไม่ โปรดทราบว่าผลลัพธ์ของฉันสอดคล้องกับคำตอบของ PherricOxide

  • ประสิทธิภาพการทำงานของ boost :: ระบบแฟ้ม :: ฟังก์ชันที่มีอยู่นั้นใกล้เคียงกับฟังก์ชั่นสถิติมากและยังพกพาได้ ฉันจะแนะนำวิธีแก้ปัญหานี้หากห้องสมุดเพิ่มสามารถเข้าถึงได้จากรหัสของคุณ

ได้รับผลการทดสอบเกณฑ์มาตรฐานด้วย Linux kernel 4.17.0 และ gcc-7.3:

2018-05-05 00:35:35
Running ./filesystem
Run on (8 X 2661 MHz CPU s)
CPU Caches:
  L1 Data 32K (x4)
  L1 Instruction 32K (x4)
  L2 Unified 256K (x4)
  L3 Unified 8192K (x1)
--------------------------------------------------
Benchmark           Time           CPU Iterations
--------------------------------------------------
use_stat          815 ns        813 ns     861291
use_open         2007 ns       1919 ns     346273
use_access       1186 ns       1006 ns     683024
use_boost         831 ns        830 ns     831233

ด้านล่างคือรหัสมาตรฐานของฉัน:

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

#include "boost/filesystem.hpp"                                                                                                                                                                                                                               

#include <benchmark/benchmark.h>                                                                                                                                                                                                                              

const std::string fname("filesystem.cpp");                                                                                                                                                                                                                    
struct stat buf;                                                                                                                                                                                                                                              

// Use stat function                                                                                                                                                                                                                                          
void use_stat(benchmark::State &state) {                                                                                                                                                                                                                      
    for (auto _ : state) {                                                                                                                                                                                                                                    
        benchmark::DoNotOptimize(stat(fname.data(), &buf));                                                                                                                                                                                                   
    }                                                                                                                                                                                                                                                         
}                                                                                                                                                                                                                                                             
BENCHMARK(use_stat);                                                                                                                                                                                                                                          

// Use open function                                                                                                                                                                                                                                          
void use_open(benchmark::State &state) {                                                                                                                                                                                                                      
    for (auto _ : state) {                                                                                                                                                                                                                                    
        int fd = open(fname.data(), O_RDONLY);                                                                                                                                                                                                                
        if (fd > -1) close(fd);                                                                                                                                                                                                                               
    }                                                                                                                                                                                                                                                         
}                                                                                                                                                                                                                                                             
BENCHMARK(use_open);                                  
// Use access function                                                                                                                                                                                                                                        
void use_access(benchmark::State &state) {                                                                                                                                                                                                                    
    for (auto _ : state) {                                                                                                                                                                                                                                    
        benchmark::DoNotOptimize(access(fname.data(), R_OK));                                                                                                                                                                                                 
    }                                                                                                                                                                                                                                                         
}                                                                                                                                                                                                                                                             
BENCHMARK(use_access);                                                                                                                                                                                                                                        

// Use boost                                                                                                                                                                                                                                                  
void use_boost(benchmark::State &state) {                                                                                                                                                                                                                     
    for (auto _ : state) {                                                                                                                                                                                                                                    
        boost::filesystem::path p(fname);                                                                                                                                                                                                                     
        benchmark::DoNotOptimize(boost::filesystem::exists(p));                                                                                                                                                                                               
    }                                                                                                                                                                                                                                                         
}                                                                                                                                                                                                                                                             
BENCHMARK(use_boost);                                                                                                                                                                                                                                         

BENCHMARK_MAIN();   

4

คุณสามารถใช้std::ifstream, funcion เช่นis_open, failยกตัวอย่างดังต่อไปนี้รหัส (คนศาล "เปิด" หมายถึงการมีอยู่ของไฟล์หรือไม่):

ป้อนคำอธิบายรูปภาพที่นี่

ป้อนคำอธิบายรูปภาพที่นี่

อ้างจากคำตอบนี้


3
all_of (begin(R), end(R), [](auto&p){ exists(p); })

Rลำดับของสิ่งที่เหมือนเส้นทางของคุณอยู่ที่ไหนและexists()มาจากมาตรฐานในอนาคตหรือการเพิ่มปัจจุบัน ถ้าคุณม้วนของคุณเองให้มันง่าย

bool exists (string const& p) { return ifstream{p}; }

ทางออกที่แตกแขนงนั้นไม่น่ากลัวอย่างยิ่งและจะไม่สามารถอธิบายไฟล์ฮุบได้

bool exists (const char* p) {
    #if defined(_WIN32) || defined(_WIN64)
    return p && 0 != PathFileExists (p);
    #else
    struct stat sb;
    return p && 0 == stat (p, &sb);
    #endif
}

PathFileExistsจำกัด ไว้ที่MAX_PATH(260) อักขระ GetFileAttributesไม่มีข้อ จำกัด นี้
เฟลิกซ์ดอมเบ

GetFileAttributesจำกัด ไว้ที่ MAX_PATH เช่นกัน เอกสารอธิบายวิธีแก้ไขหากคุณใช้พา ธ สัมบูรณ์ยูนิโคดและเติมคำนำหน้าสตริงพิเศษให้กับชื่อพา ธ ฉันคิดว่าเราปิดท้ายด้วยการตอบสนองเฉพาะ Windows เท่านั้น
จอห์น

1
GetFileAttributesWไม่มีข้อ จำกัด
ลอรีสเติ

1

ใน C ++ 17:

#include <experimental/filesystem>

bool is_file_exist(std::string& str) {   
    namespace fs = std::experimental::filesystem;
    fs::path p(str);
    return fs::exists(p);
}

5
นี่คือข้อมูลน้อยกว่าคำตอบที่ได้รับจาก Vincent 4 ปีก่อน
Jim Balter

2
ในระบบไฟล์ C ++ 17 จะไม่ถูกทดลองอีกต่อไป
Quest

0

การใช้ MFC เป็นไปได้ดังต่อไปนี้

CFileStatus FileStatus;
BOOL bFileExists = CFile::GetStatus(FileName,FileStatus);

ที่ไหนFileNameเป็นสตริงที่แสดงไฟล์ที่คุณกำลังตรวจสอบสำหรับการดำรงอยู่


0

มีเพียงวิธีเดียวที่เร็วกว่าในการตรวจสอบว่ามีไฟล์อยู่หรือไม่และหากคุณได้รับอนุญาตให้อ่านวิธีที่ใช้ภาษา C นั้นต้องการได้เร็วขึ้นและสามารถใช้ได้กับทุกรุ่นใน C ++

วิธีแก้ปัญหา : ใน C มีไลบรารีerrno.hซึ่งมีตัวแปรจำนวนเต็ม (ทั่วโลก) ภายนอกที่เรียกว่า errno ซึ่งมีหมายเลขที่สามารถใช้เพื่อรับรู้ชนิดของข้อผิดพลาด

    #include <stdio.h>
    #include <stdbool.h>
    #include <errno.h>

    bool isFileExist(char fileName[]) {
        FILE *fp = fopen(fileName, "r");
        if (fp) {
            fclose(fp);
            return true;
        }
        return errno != ENOENT;
    }

    bool isFileCanBeRead(char fileName[]) {
        FILE *fp = fopen(fileName, "r");
        if (fp) {
            fclose(fp);
            return true;
        }
        return errno != ENOENT && errno != EPERM;
    }

-4

แม้ว่าจะมีหลายวิธีที่จะทำเช่นนี้เป็นทางออกที่มีประสิทธิภาพมากที่สุดในการแก้ไขปัญหาของคุณอาจจะใช้หนึ่งในวิธีการที่กำหนดไว้ล่วงหน้า fstream ของเช่นดี () ด้วยวิธีนี้คุณสามารถตรวจสอบว่าไฟล์ที่คุณระบุมีอยู่หรือไม่

fstream file("file_name.txt");

if (file.good()) 
{
    std::cout << "file is good." << endl;
}
else 
{
    std::cout << "file isnt good" << endl;
}

ฉันหวังว่าคุณจะพบว่ามีประโยชน์นี้


4
รหัสนี้จะสร้างไฟล์หากไม่มีอยู่ดังนั้นผลลัพธ์จะเป็นจริงเสมอ คุณต้องใช้ ifstream หรือตั้งค่าพารามิเตอร์ openmode อย่างถูกต้อง
Lubo Antonov
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.