File handling in c

5 minute read

Open file

  int liFd = open(lsFileName, O_RDONLY); /* OPEN Read only*/
  int liFd = open(lsFileName, O_RDWR|O_NDELAY); /* OPEN writable */
  int liFd = open(lsFileName, O_WRONLY|O_CREAT|O_TRUNC|O_SYNC, 0666); 

. O_WRONLY : Write only . O_CREAT : Create file if it doesn’t exist . O_TRUNC : Create file after truncating if it exists . O_SYNC : Open file with SYNC mode . 0666 : File permission is 666(rw-rw-rw-)

  • open needs to choose one of them; O_RDONLY, O_WRONLY, O_RDWR
  • O_RDONLY is usually used with O_NDELAY
  • O_WRONLY is usually used with O_SYNC
  • O_SYNC means to synchronize memory buffer and file at the same time (It may be same as fdatasync() right after write())
  • O_APPEND : Move the file point to the end of file
  • O_EXCL
  • O_DSYNC
  • examples : O_RDONLY O_RDONLY|O_NDELAY O_WRONLY O_WRONLY|O_CREAT|O_TRUNC|O_SYNC O_RDWR O_RDWR|O_SYNC O_RDWR|O_NDELAY O_RDWR|O_CREAT|O_EXCL O_RDWR|O_APPEND O_RDWR|O_CREAT|O_NDELAY|O_SYNC|O_DSYNC O_RDWR|O_CREAT|O_APPEND

Read and write file

    int liFd, liRtn;
    char lsFileName[] = "./test.txt";
    char lsBuff[1024];
    char lsSeqNo[10+1];

    /* Open File */
    liFd = open(lsFileName, O_RDWR);
    if (liFd == -1) {
        printf("file open error(%s)(%d:%s)\n", lsFileName, errno, strerror(errno));

        liFd = open(lsFileName, O_CREAT|O_RDWR, 0666); /* cf. O_CREAT|O_RDWR|O_APPEND */
        if (liFd == -1) {
            printf("file open error(%s)(%d:%s)\n", lsFileName, errno, strerror(errno));
            return -1;
        }
    }

    /* Read File */
    liRtn = read(liFd, lsBuff, 10);
    if (liRtn < 0) {
        printf("Read Error\n");
    }
    printf("[RD](%s)\n", lsBuff);

    /* Write File */
    sprintf(lsSeqNo, "%010d", atoi(lsBuff) + 1);
    printf("[WR](%s)\n", lsSeqNo);
   
    if (lseek(liFd, 0L, SEEK_SET) < 0) {
        printf("file lseek error(%s)(%d:%s)\n", lsFileName, errno, strerror(errno));
        return -1;
    }
    liRtn = write(liFd, lsSeqNo, strlen(lsSeqNo));
    if (liRtn < 0)
        printf("file write error(%s)(%d:%s)\n", lsFileName, errno, strerror(errno));

    close(liFd);

fopen

FILE *fp;
fp = fopen(fname, "w+");

~

close(fd);
fclose(fp);
  • ‘r’ : Readonly, no-writable, returns error if file doesn’t exist(O_RDONLY)
  • ‘w’ : Writeonly, no-readable, create file if file doesn’t exist remove and create if file exists(O_WRONLY|O_CREAT|O_TRUNC)
  • ‘a’ : addable, move the file position to the end create new file if it doesn’t exist (O_WRONLY|O_CREAT|O_APPEND)
  • ‘r+’ : Read/Writable returns error if file doesn’t exist can be overlapped if file exists (O_RDWR|O_CREAT)
  • ‘w+’ : Read/Writable Create new file if it doesn’t exist Remove and create if file exists(O_RDWR|O_CREAT|O_TRUNC)
  • ‘a+’ : Addable, create if file doesn’t exist (O_RDWR O_CREAT O_APPEND)
  • ‘b’ : binary
  • ‘t’ : text
  • ’+’ : Add readable, r+ : Add writable

examples: “rt”, “wb”, “r+b”, “rb+”

# check file permission : access

    #include <unistd.h>
 
    if(access( lsProcPath, F_OK ))
    {
        fprintf( stderr, "access : [%s] : (%d)[%s]", lsProcPath, errno, strerror(errno));
        return -1;
    }

file synch. functions : fdatasync, fsync, fflush

fdatasync(fd)

  • write the cached data(memory buffer) to disk all at on time
  • faster than fsync

fsync(fd)

  • same as fdatasync but update modification time
  • guarantees that the files’s modification time will be updated.
  • fdatasync() and fsync() are same in linux

O_SYNC

  • it is same as open with O_SYNC flag
  • causes all writes to be committed to disk immediately

fflush(fp)

  • it is only applied to file
  • FILE *fp;

# Check the file status (stat, fstat)

     #include <sys/stat.h>

    struct stat status;
    time_t filemod_t;
      
    stat(lsFileName, &status);
    if (rval < 0) {
        UserLog("INF", "stat err : no such file[%s]", lsFileName);
    }
    
    filemod_t = status.st_mtime;

Change file position

    fseek(fp, 0L, SEEK_SET); /* 파일 처음으로 이동 */
    fseek(fp, 0L, SEEK_END); /* 파일 끝으로 이동 */
    fseek(fp, 0L, SEEK_CUR); /* 현재 파일 포인터로 이동 */
    
    if (lseek(FileID, 0L, SEEK_SET) < 0) return (-1);
    if (lseek(FileID, 0L, SEEK_END) < 0) return (-1);
    if (lseek(FileID, 0L, SEEK_CUR) < 0) return (-1);
    if (lseek(FileID, 0L, 0) < 0) return (-1);

change directory

    if (chdir("/") < 0)
        return(-1);
  • It is recommended to change the current directory to the root of the file system tree so other file systems can be unmounted while we’re running.

Change file permission

    char lsFifoNm[] = "test.fifo";
    if(mknod(lsFifoNm, S_IFIFO, 0) < 0) return -1;
    chmod(lsFifoNm, 0777);

cf. if(mknod(lsFifoNm, S_IFIFO|0777, 0) < 0) return -1;

umask

  • umask(022); —> create file with 644
  • umask(0); —> create file with 666

—> find file permission having 666, 777 find . -name “*.[c,h]” | xargs egrep ‘mknod|chmod|umask’

Linux file status

#ifdef __i386__
struct stat {
    unsigned long  st_dev;
    unsigned long  st_ino;
    unsigned short st_mode;
    unsigned short st_nlink;
    unsigned short st_uid;
    unsigned short st_gid;
    unsigned long  st_rdev;
    unsigned long  st_size;
    unsigned long  st_blksize;
    unsigned long  st_blocks;
    unsigned long  st_atime;
    unsigned long  st_atime_nsec;
    unsigned long  st_mtime;
    unsigned long  st_mtime_nsec;
    unsigned long  st_ctime;
    unsigned long  st_ctime_nsec;
    unsigned long  __unused4;
    unsigned long  __unused5;
};

#define STAT64_HAS_BROKEN_ST_INO    1

/* This matches struct stat64 in glibc2.1, hence the absolutely
 * insane amounts of padding around dev_t's.
 */
struct stat64 {
    unsigned long long  st_dev;
    unsigned char   __pad0[4];

    unsigned long   __st_ino;

    unsigned int    st_mode;
    unsigned int    st_nlink;

    unsigned long   st_uid;
    unsigned long   st_gid;

    unsigned long long  st_rdev;
    unsigned char   __pad3[4];

    long long   st_size;
    unsigned long   st_blksize;

    /* Number 512-byte blocks allocated. */
    unsigned long long  st_blocks;

    unsigned long   st_atime;
    unsigned long   st_atime_nsec;

    unsigned long   st_mtime;
    unsigned int    st_mtime_nsec;

    unsigned long   st_ctime;
    unsigned long   st_ctime_nsec;

    unsigned long long  st_ino;
};

#else /* __i386__ */

struct stat {
    unsigned long   st_dev;
    unsigned long   st_ino;
    unsigned long   st_nlink;

    unsigned int    st_mode;
    unsigned int    st_uid;
    unsigned int    st_gid;
    unsigned int    __pad0;
    unsigned long   st_rdev;
    long        st_size;
    long        st_blksize;
    long        st_blocks;  /* Number 512-byte blocks allocated. */

    unsigned long   st_atime;
    unsigned long   st_atime_nsec;
    unsigned long   st_mtime;
    unsigned long   st_mtime_nsec;
    unsigned long   st_ctime;
    unsigned long   st_ctime_nsec;
    long        __unused[3];
};
#endif


int liRtn;
struct stat status;

liRtn = stat(gCurMonFile, &status);

st_ctime : created date st_mtime : modified date st_atime : access date st_size : file size st_ino : file inode number

strip command

  • The strip command optionally removes the following informations. . line number information . relocation information
    . the debug section
    . the comment section
    . file headers
    . all or part of the symbol table from the XCOFF object files

get file size

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/stat.h>


int getFileLen(char *msg_id) {

    char fname[128];
    char *env_dir;
    int liRtn, liLen = 0;

    char TmpStr[MAX_FILE_SIZE];

    env_dir = getenv("CTIMON_HOME");
    if (env_dir == NULL) {
        fprintf(stderr, "No env. variable CTIMON_HOME\n");
        return 0;
    }

    sprintf(fname, "%s/dat/%s.xml", env_dir, msg_id);

    /* File Length Test */
    struct  stat ltStat;
    liRtn = stat(fname, &ltStat);
    liLen = ltStat.st_size;

    if (liRtn != 0)
        return -1;
    else
        return liLen;
}

Tags:

Categories:

Updated:

Leave a comment