Lion King
Lion King

Reputation: 33823

How to check if a file exists before creating a new file

I want to input some contents to a file, but I'd like to check first if a file with the name I wish to create exists. If so, I don't want to create any file, even if the file is empty.

My attempt

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;
}

Is there any way to do what I want?

Upvotes: 27

Views: 112341

Answers (9)

rabensky
rabensky

Reputation: 2934

Looked around a bit, and the only thing I find is using the open system call. It is the only function I found that allows you to create a file in a way that will fail if it already exists

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

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

Note that you have to give permissions since you are creating a file.

This also removes any race conditions there might be

Upvotes: 2

Richard
Richard

Reputation: 8758

C++17, cross-platform: Using std::filesystem::exists and 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.
    }
}

Upvotes: 0

James Hirschorn
James Hirschorn

Reputation: 8046

As of C++17 there is:

if (std::filesystem::exists(pathname)) {
   ...

Upvotes: 6

Vaibhav
Vaibhav

Reputation: 1

The easiest way to do this is using ios :: noreplace.

Upvotes: -1

Racky
Racky

Reputation: 1183

I just saw this test:

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

Upvotes: 0

alexbuisson
alexbuisson

Reputation: 8509

you can also use Boost.

 boost::filesystem::exists( filename );

it works for files and folders.

And you will have an implementation close to something ready for C++14 in which filesystem should be part of the STL (see here).

Upvotes: 13

dumbledad
dumbledad

Reputation: 17535

Try this (copied-ish from Erik Garrison: https://stackoverflow.com/a/3071528/575530)

#include <sys/stat.h>

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

stat returns 0 if the file exists and -1 if not.

Upvotes: 7

Mats Petersson
Mats Petersson

Reputation: 129524

Assuming it is OK that the operation is not atomic, you can do:

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;
}
... 

Note that this doesn't work if you run multiple threads trying to create the same file, and certainly will not prevent a second process from "interfering" with the file creation because you have TOCTUI problems. [We first check if the file exists, and then create it - but someone else could have created it in between the check and the creation - if that's critical, you will need to do something else, which isn't portable].

A further problem is if you have permissions such as the file is not readable (so we can't open it for read) but is writeable, it will overwrite the file.

In MOST cases, neither of these things matter, because all you care about is telling someone that "you already have a file like that" (or something like that) in a "best effort" approach.

Upvotes: 32

CBIII
CBIII

Reputation: 865

Try

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

From: How to check if a file exists and is readable in C++?

or you could use boost functions.

Upvotes: 8

Related Questions