linux——3.文件操作

/*
 *       file.cpp: for linux file methods
 */

#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>

#include <unistd.h>

#include <stdio.h>

#include <dirent.h>

#include <iostream>
using namespace std;


#define UNIT_TEST   1

// file class
class File
{
public:
    File()
    {
        m_fd = -1;
    }
    ~File()
    {
        close();
    }
    
    /*
    *       system lib call
    */
    // open
    // oflags: O_RDONLY, O_WRONLY, O_RDWR; O_APPEND, O_TRUNC, O_CREAT, O_EXCL
    // mode: S_IRUSR, S_IWUSR, S_IXUSR..
    bool open(const char *path, int oflags = O_RDWR, int mode = S_IRUSR | S_IWUSR)
    {
        m_fd = ::open(path, oflags, mode);
        return m_fd != -1;
    }
    
    // close
    void close()
    {
        if (m_fd != -1)
        {
            ::close(m_fd);
            m_fd = -1;
        }
    }
    
    // write
    size_t write(const void *buf, size_t nbytes)
    {
        if (m_fd != -1)
        {
            return ::write(m_fd, buf, nbytes);
        }
        
        return -1;
    }
    
    // read
    size_t read(void *buf, size_t nbytes)
    {
        if (m_fd != -1)
        {
            return ::read(m_fd, buf, nbytes);
        }
        
        return -1;
    }
    
    // copy
    static bool copy(const char *path, const char *pathout)
    {
        File in;
        if (!in.open(path, O_RDONLY))
        {
            return false;
        }
        
        File out;
        if (!out.open(pathout, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR))
        {
            return false;
        }
        
        char buf[1024];
        int nread;
        while ((nread = in.read(buf, sizeof(buf))) > 0)
        {
            out.write(buf, nread);
        }
        
        return true;
    }
    
    // seek
    off_t lseek(off_t offset, int whence = SEEK_SET)
    {
        if (m_fd != -1)
        {
            return ::lseek(m_fd, offset, whence);
        }
        return -1;
    }
    
    
    /*
     *       std io lib
     */
    // fopen, fclose, fread, fwrite, fflush, fsee,, fgetc, fputc, fprintf..
    
    /*
     *      maintain file and folder
     */
    // change file or folder access priority
    static int chmod(const char *path, mode_t mode)
    {
        return ::chmod(path, mode);
    }
    
protected:
    int     m_fd;
};

// directory
class Directory
{
public:
    Directory()
    {
        m_dir = NULL;
    }
    ~Directory()
    {
        close();
    }
    
    // make dir
    static int mkdir(const char *path, mode_t mode)
    {
        return ::mkdir(path, mode);
    }
    
    // remove dir
    // only if the dir is empty
    static int rmdir(const char *path)
    {
        return ::rmdir(path);
    }
    
    // change dir
    static int chdir(const char *path)
    {
        return ::chdir(path);
    }
    
    // get current work directory
    static char *getcwd(char *buf, size_t size)
    {
        return ::getcwd(buf, size);
    }
    
    // open dir
    bool open(const char *name)
    {
        m_dir = ::opendir(name);
        return m_dir != NULL;
    }
    
    // read dir
    // dirent: d_ino inode num, d_name file name
    dirent* read(DIR *dir = NULL)
    {
        if (!dir)
            dir = m_dir;
        if (dir)
            return readdir(dir);
        
        return NULL;
    }
    
    void close()
    {
        if (m_dir)
        {
            closedir(m_dir);
            m_dir = NULL;
        }
    }
    
    long int tell(DIR *dir = NULL)
    {
        if (!dir)
            dir = m_dir;
        if (dir)
            return telldir(dir);
        
        return -1;
    }
    
    void seek(DIR *dir = NULL, long int loc = 0)
    {
        if (!dir)
            dir = m_dir;
        if (dir)
            seekdir(dir, loc);
    }
    
    // scan
    static void scan(const char *path)
    {
        // open dir
        Directory dir;
        if (!dir.open(path))
        {
            cout << "open dir failed:" << path << endl;
            return;
        }
        
        // change dir
        chdir(path);
        
        // scan dir
        struct dirent *entry;
        struct stat statbuf;
        while ((entry = dir.read()) != NULL)
        {
            lstat(entry->d_name, &statbuf);
            if (S_ISDIR(statbuf.st_mode))
            {
                // found a dir, but ignore . and ..
                if (!strcmp(".", entry->d_name)
                    || !strcmp("..", entry->d_name))
                {
                    continue;
                }
                scan(entry->d_name);
            }
            else
            {
                cout << entry->d_name << endl;
            }
        }
        
        chdir("..");
        dir.close();
    }
protected:
    DIR*    m_dir;
};


#if UNIT_TEST == 1
int main()
{
    File file;
    
    // create open.txt
    if (!file.open("open.txt", O_RDWR | O_CREAT))
    {
        cout << "create file open.txt error.\n";
    }
    else
    {
        // write
        char buf[] = "this is adfan\nit's true\n";
        file.write(buf, sizeof(buf));
        
        file.close();
    }
    
    // open
    if (!file.open("open.txt"))
    {
        cout << "open file open.txt error.\n";
    }
    else
    {
        char buf[256] = {0};
        file.read(buf, 256);
        cout << buf << endl;
    }
    
    
    // close file
    file.close();
    
    // copy
    File::copy("open.txt", "open_out.txt");
    
    char dir[256];
    cout << Directory::getcwd(dir, 256) << endl;
    
    // scan
    Directory::scan(dir);
}
#endif

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章