Linux 文件系统编程之系统调用和标准I/O库

系统调用

访问设备驱动程序的底层函数主要有:
open:打开文件或者设备。
read:从打开的文件或者设备里面读取数据。
write:向文件或者设备写数据。
close:关闭文件或者设备。
open系统调用:
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
int open (const char *path, int flags);
int open (const char *path, int flags, mode_t mode);
path表示文件名,flags用来定义准备对打开的文件进行操作的动作。
如果open调用成功,则返回一个新的文件描述符(非负整型);如果失败,就返回-1close系统调用:
#include <unistd.h>
int close(int filedes);
成功返回0;出错返回-1read系统调用:
#include <unistd.h>
ssize_t read(int filedes, const void *buf, size_t nbytes);< publishblog.blogchina.com http:>
将n个字节从文件描述符对应的文件读出放入到buf中。成功则返回实际的读取字节数。

write系统调用:
#include <unistd.h>
ssize_t write(int filedes, const void *buf, size_t nbytes);
返回值是实际写入的字节数(可能会小于nbytes);如果返回值是0,表示没有写入任何数据;如果返回值是-1,表示在write调用中出错了。
将n个字节从buf中写入到文件描述符对应的文件中。

常用标准I/O库文件函数:fopen,fwrite,fread,fclose,fflush,fseek,fgets,getchar,fputs等系列的函数
他们与系统调用的一个主要的区别在于,这是带缓冲的函数,操作的对象不是int型的文件描述符,而是fopen返回的FILE型的文件指针(*fp).对应的标准输入,输出,出错为stdin,stdout,stderr文件指针。
我把这些函数的用法全都写在这里:

#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <time.h>

#define SIZE  1024

// fopen
int main0()
{
    FILE* fp = fopen ("abc", "ab+");
    if (NULL == fp)
    {
        perror ("fopen");
        return -1;
    }

    printf ("打开文件成功\n");
    return 0;
}

// fread
int main1()
{
    FILE* fp = fopen ("BTree.c", "ab+");
    if (NULL == fp)
    {
        perror ("fopen");
        return -1;
    }

    char buf[SIZE] = {0};

    // feof 判断是否读到文件结尾,如果读到文件结尾,它返回一个非0 的值
    int ret;
    while (ret = fread (buf, sizeof(char), SIZE-1, fp))
    {
        buf[ret*sizeof(char)] = '\0';
        printf ("%s\n", buf);
    }

    if (0 == ret && !feof(fp))
    {
        perror ("fread");
        return -1;
    }

    printf ("文件读取结束\n");
    return 0;
}

// fwrite
int main2()
{
    FILE* fp = fopen ("1.ppt", "ab+");
    if (NULL == fp)
    {
        perror ("fopen");
        return -1;
    }

    FILE* fp1 = fopen ("2.ppt", "ab+");
    if (NULL == fp1)
    {
        perror ("fopen");
        return -1;
    }

    char buf[SIZE] = {0};

    // feof判断是否读到文件结尾,如果读到文件结尾,它返回一个非0 的值
    int ret;
    while (ret = fread (buf, sizeof(char), SIZE, fp))
    {
        fwrite (buf, sizeof(char), ret, fp1);
    }

    if (0 == ret && !feof(fp))
    {
        perror ("fread");
        return -1;
    }

    printf ("文件读取结束\n");

    fclose (fp);
    fclose (fp1);
    return 0;
}

// fgetc
int main3()
{
    FILE* fp = fopen ("1.ppt", "ab+");
    if (NULL == fp)
    {
        perror ("fopen");
        return -1;
    }

    FILE* fp1 = fopen ("2.ppt", "ab+");
    if (NULL == fp1)
    {
        perror ("fopen");
        return -1;
    }

    char buf[SIZE] = {0};

    // feof 判断是否读到文件结尾,如果读到文件结尾,它返回一个非0 的值
    int ret;
    while(1)
    {
        int  c = fgetc (fp);
        if (EOF == c)
        {
            break;
        }
        fputc (c, fp1);
    }

    fclose (fp);
    fclose (fp1);
    return 0;
}

// 数据获取
/***************************************************************/
typedef struct student
{
    int id;
    char name[20];
}STU;


void write_data(STU* a, int len)
{
    FILE* fp = fopen ("student", "ab+");
    if (NULL == fp)
    {
        perror ("fopen");
        return;
    }   

    // 要写入个数
    fwrite (&len, sizeof(int), 1, fp);

    int i;
    for (i = 0; i < len; i++)
    {
        // 写入数据长度
        len = sizeof(a[i]);     
        fwrite (&len, sizeof(int), 1, fp);

        // 写入数据
        fwrite (&a[i], sizeof(STU), 1, fp);
    }

    fclose (fp);
}


// 读取数据
void read_data()
{
    FILE* fp = fopen ("student", "ab+");
    if (NULL == fp)
    {
        perror ("fopen");
        return;
    }

    // 读记录的个数
    int count;
    fread (&count, sizeof(int), 1, fp);

    printf ("记录个数是:%d\n", count);
    int i;
    STU tmp;
    for (i = 0; i < count; i++)
    {
        int len;
        fread (&len, sizeof(int), 1, fp);

        // 读取数据
        fread (&tmp, len, 1, fp);
        printf ("id = %d, name = %s\n", tmp.id, tmp.name);
    }

    fclose (fp);
}

int main4()
{
    int i;
    STU a[20];

    for (i = 0; i < 20; i++)
    {
        a[i].id = i;                
        sprintf (a[i].name, "zhang%d", i);
    }

    int len = sizeof(a)/sizeof(a[0]);   

    // 写数据
    write_data(a, len);

    // 读数据
    read_data();

    return 0;
}
/***************************************************************/


// open
int main5()
{
    close(1);

    // 打开一个文件
    int fd = open ("test.txt", O_RDWR | O_CREAT, S_IRUSR | S_IWUSR |   S_IXUSR);
    // int fd = open("test.txt", O_RDONLY);

    if (-1 == fd)
    {
        printf ("打开文件失败\n");
        perror ("open");
        printf ("%s\n", strerror(errno));          
    }

    printf ("fd = %d\n", fd);
    printf ("asdadsafsfkj\n", fd);
    printf ("asdadsafsfkj\n", fd);
    printf ("asdadsafsfkj\n", fd);
    printf ("asdadsafsfkj\n", fd);
    printf ("asdadsafsfkj\n", fd);
    printf ("asdadsafsfkj\n", fd);
    printf ("asdadsafsfkj\n", fd);
    // fflush(stdout);

    close(fd);

    return 0;

}

// read
/***************************************************************/
int main6()
{
    int fd = open ("BTree.c", O_RDONLY, 0777);
    if (-1 == fd)
    {
        perror ("open");
        return -1;
    }

    // 缓冲区  
    char buf[SIZE] = {0};
    ssize_t ret = read (fd, buf, SIZE-1);
    if (-1 == ret)
    {
        perror ("read");
    }

    // 返回值为0 代表读到文件结尾
    if (0 == ret)
    {
        printf ("文件读取结束\n");
    }

    printf ("len = %d\n", strlen(buf));
    printf ("读到%d字节:%s\n", ret, buf);

    return 0;
}

// 缓冲区覆盖问题
int main7()
{
    int fd = open ("BTree.c", O_RDONLY, 0777);
    if (-1 == fd)
    {
        perror ("open");
        return -1;
    }

    char buf[SIZE] = {0};

    while(1)
    {
        ssize_t ret = read (fd, buf, SIZE-1);
        if (-1 == ret)
        {
            perror ("read");
        }

        // 返回值为0 代表读到文件结尾
        if (0 == ret)
        {
            printf ("文件读取结束\n");
            break;
        }

        // printf ("len = %d\n", strlen(buf));
        // printf ("读到%d 字节: %s\n", ret, buf);
        printf ("%s", buf);
    }

    return 0;
}

// 读取数据之前清空缓冲区
int main8()
{
    int fd = open ("BTree.c", O_RDONLY, 0777);
    if (-1 == fd)
    {
        perror ("open");
        return -1;
    }

    char buf[SIZE] = {0};

    while(1)
    {
        memset (buf, 0, SIZE);          // 清空缓冲区
        ssize_t ret = read (fd, buf, SIZE-1);
        if (-1 == ret)
        {
            perror ("read");
        }

        if (0 == ret)
        {
            printf ("文件读取结束\n");
            break;
        }
        printf ("%s", buf); 
    }

    return 0;
}

// 每次读完数据之后讲下一个字节置为'\0';
int main9()
{
    int fd = open ("BTree.c", O_RDONLY, 0777);
    if (-1 == fd)
    {
        perror ("open");
        return -1;
    }

    char buf[SIZE] = {0};

    while(1)
    {
        ssize_t ret = read (fd, buf, SIZE-1);
        if (-1 == ret)
        {
            perror ("read");
        }

        if (0 == ret)
        {
            printf ("文件读取结束\n");
            break;
        }

        buf[ret] = '\0';
        printf ("%s", buf);
        }

        return 0;
}

// 读一个完整的大数据
int main10()
{
    int fd = open ("BTree.c", O_RDONLY, 0777);
    if (-1 == fd)
    {
        perror ("open");
        return -1;
    }

    char buf[SIZE] = {0};
    char* p = buf;
    int count = SIZE - 1;               // 每次要读的数据个数
    ssize_t ret =0;
    while (ret = read (fd, p, count))
    {
        // 出错
        if (-1 == ret)
        {
            if (errno == EAGAIN || errno == EINTR)
            {
                continue;
            }
            break;
        }
        printf ("sfjsfsjfs\n");
        // 读完
        if (ret == count)
        {
            break;
        }
        count -= ret;                   // 下一次要读的数据
        p += ret;
    }

    printf ("len = %d\n", strlen(buf));
    // printf ("%s\n", buf);

    return 0;
}
/***************************************************************/


// write
int main11()
{
    int fd = open ("abc", O_WRONLY|O_CREAT, 0777);
    if (-1 == fd)
    {
        perror ("open");
        return -1;
    }
    char buf[SIZE] = {0};

    while(1)
    {
        fgets (buf, SIZE, stdin);
        if (0 == strncmp ("end", buf, 3))
        {
            break;
        }

        ssize_t ret = write (fd, buf, strlen(buf));
        if (-1 == ret)
        {
            perror ("write");
        }

        printf ("要写的字节数:%d,实际写的字节数:%d\n", SIZE, ret);
    }

    close(fd);
    return 0;
}

// 文件复制
int main12()
{
    // 打开要读的文件
    int fd1 = open ("1.ppt", O_RDONLY);
    if (-1 == fd1)
    {
        perror ("open fd1");
        return -1;
    }

    int fd2 = open ("2.ppt", O_WRONLY|O_CREAT, 0777);
    if (-1 == fd2)
    {
        perror ("open fd2");
        return -1;
    }

    int ret = 0;
    char buf[SIZE] = {0};
    while (ret = read (fd1, buf, SIZE))
    {
        if (-1 == ret)
        {
            perror("read");
            break;
        }

        write (fd2, buf, ret);
    }
    printf ("文件复制完成\n");
    close (fd1);
    close (fd2);

    return 0;
}

// lseek
int main13()
{
    // 打开要读的文件
    int fd = open ("abc2", O_RDWR|O_CREAT, 0777);
    if (-1 == fd)
    {
        perror ("open fd1");
        return -1;
    }

    // 设置这个文件的偏移指针
    lseek (fd, 20, SEEK_SET);

    char* buf = "hello";

    write (fd, buf, strlen(buf));
    close (fd);

    return 0;
}

// 创建一个大文件
int main14()
{
    // 打开要读的文件
    int fd = open ("big", O_RDWR|O_CREAT, 0777);
    if (-1 == fd)
    {
        perror ("open fd1");
        return -1;
    }

    // 设置这个文件的偏移指针到1G处
    lseek (fd, 1024*1024*1024, SEEK_SET);

    char* buf = "hello";    
    write (fd, "a", 1);
    close (fd);

    return 0;
}

// printf缓冲
int main15()
{
    while(1)
    {
        printf ("a");
        usleep (2000);
    }

    return 0;
}

// 文件偏移指针测试1
int main16()
{
    // 打开要读的文件
    int fd = open ("big", O_RDWR|O_CREAT, 0777);
    if (-1 == fd)
    {
        perror("open fd1");
        return -1;
    }

    printf ("%d\n", fd);
    // 设置这个文件的偏移指针到1G处
    lseek (fd, 20, SEEK_SET);

    printf ("等待2些数据\n");
    getchar();

    char* buf = "hello";

    write (fd, "a", 1);
    getchar();

    close (fd);
    return 0;
}

// 文件偏移指针测试2
int main17()
{
    // 打开要读的文件
    int fd1 = open ("abc", O_RDWR|O_CREAT, 0777);
    if (-1 == fd1)
    {
        perror ("open fd1");
        return -1;
    }

    printf ("abc fd = %d\n", fd1);

    int fd = open ("big", O_RDWR|O_CREAT, 0777);
    if (-1 == fd)
    {
        perror ("open fd");
        return -1;
    }

    printf ("bif fd = %d\n", fd);
    // 设置这个文件的偏移指针到 1G处
    lseek (fd, 10, SEEK_SET);

    char *buf = "12345";

    write (fd, buf, strlen(buf));
    getchar();
    close (fd);

    return 0;
}

/***************************************************************/
// 随机分组
// 函数功能:互换
void swap (int* a, int i, int j)
{
    int tmp = a[i];
    a[i]    = a[j];
    a[j]    = tmp;
}
// 函数功能:打印
void printA (int* a, int len)
{
    int i;

    for (i = 0; i < len; i++)
    {
        if (0 == i % 4)
        {
            printf ("\n");
        }
        printf ("%4d", a[len-i-1]);
    }

    putchar ('\n');
}

int main18()
{
    srand ((unsigned int)time(NULL));

    int a[40];
    int i;
    int len = 40;
    for (i = 0; i < 40; i++)
    {
        a[i] = i;
    }

    for (i = len-1; i > 0; i--)
    {
        int index = rand() % (i+1);    // 获取随机数
        swap (a, index, i);            // 将获得的数和最后一个互换
    }

    printA (a, len);

    return 0;
}
/***************************************************************/


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值