Thread: How to check if file exists ?

  1. #1
    Registered User
    Join Date
    Apr 2007
    Posts
    111

    How to check if file exists ? [Tutorial + could it be moved to linux forum?]

    some time ago i wrote a small post about how to check if file exists
    the code is using open() but today i got a comment that i should use stat() so i read the man file and tried the next.
    The question is :
    is it good enough explanation and is it the right approach ?


    Code:
    /************************************************************************
     *
     * Purpose: This program will demonstrate the use of stat() on linux 
     *
     * Author:  Jabka Atu
     *
     * Date:    13 October 2007
     *          
     *
     * Notes:   I used  M J Leslie's orignal example to learn and 
     *          used his file as skelton for this
     *
     *
     ************************************************************************/
    
    
    #include <sys/stat.h>			/* declare the 'stat' structure	*/
    #include <sys/types.h>			
    #include <unistd.h>		
    #include <stdio.h>			    /* printf			*/
    #include <time.h>
    
    #define  FILENAME "/tmp"		/* PUT YOUR FILE NAME HERE	*/
    
    /************************************************************************/
    
    
    
    void file_stat(char * filename);
    
    
    main()
    {
      file_stat(FILENAME);
    }
    
    
    
    void file_stat(char * filename)
    {
      struct stat stat_p;		/* 'stat_p' is a pointer to a structure
    				 			 * of type 'stat'.  			*/
    
    							/* Get stats for file and place them in
    				 			 * the structure.			*/
      /*
         To use Macro you should do the next:
         write the macro and as it argument use the defined types
         for example:
         Macro = S_ISDIR(mode)
         Argumant = mode
         usage:
         S_ISDIR(stat_p.st_mode); // st_mode is a predifined field
     
      	 now the MACROs for state are (thnx to http://linux.die.net/man/2/stat )
      
      
      		S_ISREG(m)
        		is it a regular file? 
    		S_ISDIR(m)
        		directory? 
    		S_ISCHR(m)
        		character device? 
    		S_ISBLK(m)
    	    	block device? 
    		S_ISFIFO(m)
        		FIFO (named pipe)? 
    		S_ISLNK(m)
        		symbolic link? (Not in POSIX.1-1996.) 
    		S_ISSOCK(m)
      			socket? (Not in POSIX.1-1996.)
       */  
      
      stat (filename, &stat_p);
      printf("This will print several tests on your file \n");
      printf("The answer is in boolean \n 0 - No \n 1 - yes\n");
    			
      printf("\tIs it \n\texsits ?\t\t%d \n",S_ISREG(stat_p.st_mode));
      printf("\tDirectory ?     \t%d \n",S_ISDIR(stat_p.st_mode));
      printf("\tCharecter Device  \t%d\n",S_ISCHR(stat_p.st_mode));
      printf("\tblock device?   \t%d\n",S_ISBLK(stat_p.st_mode));
      printf("\tFIFO (named pipe)? \t%d \n",S_ISFIFO(stat_p.st_mode));
      printf("\tsocket?     \t\t%d\n",S_ISSOCK(stat_p.st_mode));
    }
    
    /************************************************************************/
    Last edited by jabka; 10-13-2007 at 01:40 PM.
    why Gaos didn't had a wife ?
    http://bsh83.blogspot.com

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Well it depends how portable you want the answer to be.
    If you're OK restricting yourself to POSIX systems, then stat() should be fine.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    If you want ANSI-compatible code, the closest you can get is to try opening the file for reading.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  4. #4
    Registered User
    Join Date
    Apr 2007
    Posts
    111
    so i should work with fopen() and work with errno ?
    why Gaos didn't had a wife ?
    http://bsh83.blogspot.com

  5. #5
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    I don't think errno is ANSI standard. You can just check to see if fopen() returned NULL or not.

    Of course, this method has many flaws. You might not have the permissions to open the file, for example, even though it may exist.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  6. #6
    Registered User
    Join Date
    Apr 2007
    Posts
    111
    i goggled a bit and asked on irc (and got a stfu) and found in msdn the use of _stat()

    also im trying to figure if fopen will set errno as i needed .
    so i guess errno is ansi
    why Gaos didn't had a wife ?
    http://bsh83.blogspot.com

  7. #7
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  8. #8
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >I don't think errno is ANSI standard.
    IIRC, errno isn't required to be set by anything in the stdio library except fsetpos, fgetpos, and ftell.
    My best code is written with the delete key.

  9. #9
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    If you use open() to check if a file exists and you want to create it if it doesn't exist, you'll probably want to use the O_EXCL flag in the call to open() to prevent a race condition.

  10. #10
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    If you're using open(), you're using POSIX code, and you might as well use stat(). Unless you want to use the file afterwards or something.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  11. #11
    Registered User
    Join Date
    Apr 2007
    Posts
    111

    I found an ANSI solution (i think )

    Howdy,..

    after a few hints and stfu's i found a solution (or think i did ).

    using perror(NULL) to print the error (it will check only the lest errno error but it is a good begning) and using fopen() (it is an ANSI ):

    Code:
    /*
     *
     * An ANSI solution for checking if file exists.
     *
     * Thnx to dwks , Tzafrir , salem , Mika0x65 and more for the guidance ..
     */
     
    #include <stdio.h>
    #include <errno.h>
    
    #define FILENAME "myfile"
    
    
    
    int main(){
    	FILE *fp = NULL;
            fp = fopen(FILENAME,"r+");
    	if (fp == NULL)
    	{
    		perror(NULL); //will print the text relative to errno
    	}
    	return 0;
    }
    i don't have windows to check if it will work and profuce the correct error (nonexistent and no privileges )
    Last edited by jabka; 10-14-2007 at 04:29 PM. Reason: removed extern int errno since it is a mistake
    why Gaos didn't had a wife ?
    http://bsh83.blogspot.com

  12. #12
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    I'm pretty sure that "extern errno" is not correct. It should be fine to just include <errno.h> and nothing else. Saying something like "extern errno" won't work when errno is a macro that replaces with a function call, uses an array index by thread ID or a dig into some TLS (Thread Local Storage) variable.

    The reason errno isn't just simply a global variable is that people who use multithreading want errno to still work "as expected", and if you have ONE global variable used by multiple threads, it needs to have locks and protection to prevent one function call from overwriting the result with another function call in another thread. That would be complex and convoluted (and basicly every function that uses errno may need this locking mechanism, since it's very difficult to figure out what particular scenarios the lock is REALLY necessary and which cases are not).

    So, instead the implementation inside the C-library separates a different errno per thread in some way or another. How this is done will vary depending on the OS and compiler vendor.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  13. #13
    Registered User
    Join Date
    Apr 2007
    Posts
    111
    noted thank you .
    so i actualy don't need to do extern errno in any C or C++ code ?
    why Gaos didn't had a wife ?
    http://bsh83.blogspot.com

  14. #14
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Including errno.h will do the right thing for you.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  15. #15
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    Quote Originally Posted by dwks View Post
    If you're using open(), you're using POSIX code, and you might as well use stat(). Unless you want to use the file afterwards or something.
    stat() is fine if you aren't actually trying to create a file, but if you want to create a file only if it doesn't already exist, stat() won't help you because you still need to call open() after stat() and in between those calls someone else could quickly slip in and create the file which could lead to security issues...

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. To find the memory leaks without using any tools
    By asadullah in forum C Programming
    Replies: 2
    Last Post: 05-12-2008, 07:54 AM
  2. C++ std routines
    By siavoshkc in forum C++ Programming
    Replies: 33
    Last Post: 07-28-2006, 12:13 AM
  3. How to check if a file exists
    By ElWhapo in forum C++ Programming
    Replies: 3
    Last Post: 12-29-2004, 05:16 PM
  4. Possible circular definition with singleton objects
    By techrolla in forum C++ Programming
    Replies: 3
    Last Post: 12-26-2004, 10:46 AM
  5. check if the file exists
    By ipe in forum C Programming
    Replies: 2
    Last Post: 03-15-2003, 09:18 AM