I/O编程

一、标准IO

1.1、概述

标准IO

  • 是ANSI C提供的函数接口,在文件IO的基础上封装出来的。任何兼容标准C库的操作系统都可以使用接口,具有更好的移植性
  • 标准IO在执行时也会用到系统调用,为了增加内核的工作效率,减少资源浪费,在文件IO的基础上封装了缓冲区。

缓冲区

  1. 全缓冲:当缓冲区满或执行flush操作时才会进行磁盘操作;缓冲区满才进行实际的IO操作 4k
  2. 行缓冲:当在输入输出中遇到换行符时执行IO操作 1k
  3. 无缓冲:不对IO操作进行缓冲,在对流的读写时会立刻操作实际文件

流指针

  • 当用标准IO打开一个文件时,就会创建一个FILE结构体描述该文件;把这个FILE结构体称为流。
  • 标准IO操作文件返回的是文件流指针(FILE *)描述;文件IO打开后用文件描述符(fd)描述。

三种标准IO

标准输入流(键盘)0STDIN_FILENOstdin
标准输出流(显示器)1STDOUT_FILENOstdout
标准错误流2STDERR_FILENOstderr

1.2、标准IO编程

1.文件的打开

FILE *fopen (const char *path, const char *mode);

  • Path: 普通文件当前路径不需要加目录,其他要使用完整的路径
  • Mode:文件的打开模式
  • 返回值:成功时返回流指针,出错返回NULL,所以使用fopen函数必须判断是否为空

文件的打开模式

mode描述
“r” 或 “rb”以只读方式打开文件,文件必须存在。
“r+” 或 ”r+b”以读写方式打开文件,文件必须存在。
“w” 或 “wb”以只写方式打开文件,若文件存在则文件长度清为0。若文件不存在则创建。只写一次
“w+” 或 “w+b”以读写方式打开文件,其他同”w”。
“a” 或 “ab”以只写方式打开文件,若文件不存在则创建;向文件写入的数据被追加到文件末尾。
“a+” 或 “a+b”以读写方式打开文件。其他同”a”

2.文件的关闭

int flose(FILE *stream);

  • stream:以打开的流指针
  • 返回值:成功:0 失败:EOF
  1. 流关闭时自动刷新缓冲中的数据并释放缓冲区,比如:常规文件把缓冲区内容写入磁盘
  2. 当一个程序正常终止时,所有打开的流都会被关闭
  3. 流一旦关闭后就不能执行任何操作
  4. fclose()函数的入参stream必须保证为非空,否则出现断错误。不能关闭一个不存在的文件

3.错误处理

  • perror()
    void perror(const char *s);
    • s:在标准错误流上输出的信息
    • perror(“”);
  • strerror()
    • char *strerror(int errnum);
    • 参数:错误码
    • 返回值:错误码对应的错误信息
    • printf(“%s\n”, strerror(errno)) ;

示例

#include <string.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>                                                             

int main(){
    FILE *fp;

    if((fp = fopen("./1.txt", "r")) == NULL){
        perror("fopen");
        printf("%s\n",strerror(errno));
        exit(1);
    }   
    fclose(fp);

    return 0;
}

//运行结果
fopen: No such file or directory
No such file or directory

4.流的读写

4.1.按字符输入/输出
  • 按字符输入
    int fgetc(FILE *stream);
    int getc(FILE *stream); //宏
    int getchar(void); 只能读取键盘输入
    • stream:要输入的文件流
    • 返回值:成功:返回读取的字符 若到文件末尾或出错时返回EOF
  1. getchar() 等同与fgetc(stdin)
  2. getc和fgetc区别 一个是宏 一个是函数
  3. 函数返回值时int型不是char型,主要是为了扩展返回值的范围
  4. stdin也是FILE*的指针,是系统定义好的,指向的是标准输入(键盘输入)
  5. 打开文件后读取,是从文件开头开始读。读完一个后读写指针会后移。读写注意文件位置
  6. 调用getchar会造成阻塞,等待键盘输入
  • 按字符输出
    int fputc(int c, FILE *stream);
    int putc(int c, FILE *stream);
    int putchar(int c);
    • 成功时返回写入的字符;出错时返回EOF
    • putchar©等同于fputc(c, stdout)
    • 注意:返回和输入参数都是int类型

练习

#include <stdio.h>

int main(){
    int c;

    while(1){
        c = fgetc(stdin);           //从键盘读取一个字符
        if(c >= '0' && c <= '9')    //输入的是数字,输出
            fputc(c, stdout);
        if(c == '\n')               //遇到换行符,跳出循环                      
            break;
    }   
    puts("");
    return 0;
}

//运行结果
q2312fadsf
2312
4.2.按行输入/输出
  • 按行输入
    char *gets(char *s);(不推荐使用)
    char *fgets(char *s, int size, FILE *stream);(读的内容,读多少,从哪里读)
    • s:存放输入字符串的缓冲区首地址
    • size:输入的字符串长度
    • stream:对应的流
    • 返回值:成功返回s;失败或到文件末尾返回NULL
  1. gets函数已经被淘汰,因为会导致缓冲区溢出
  2. fgets函数第二个参数,输入的数据超出size,size-1的字符会保存到缓冲区,最后添加‘\0’,如果输入数据小于size-1,后边会添加换行符
  • 按行输出
    int puts(const char *s);
    int fputs(const char *s, FILE *stream);
    • s:存放输入字符串的缓冲区首地址
    • stream:对应的流
    • 成功时返回输出的字符个数;出错时返回EOF
  1. puts将缓冲区s中的字符串输出到stdout,并追加’\n’
  2. fputs将缓冲区s中的字符串输出到stream,不追加 ‘\n’

练习

//计算一个文本文件的行数                                                        
#include <stdio.h>
#include <string.h>

int main(int argc, const char *argv[])
{
    int line = 0;
    char buf[128];
    FILE *fp;

    if(argc < 2) {
        printf("usage: %s<file>\n",argv[0]);
        return -1;
    }
    if((fp = fopen(argv[1], "r")) == NULL) {
        perror("fail to open");
        return -1;
    }
    while(fgets(buf, 128, fp) != NULL) {
        if(buf[strlen(buf)-1] == '\n')
            line++;
    }
    printf("the line of %s is %d\n", argv[1], line);

    return 0;
}
4.3.按指定对象大小输入/输出

size_t fread(void *ptr, size_t size, size_t n, FILE *fp);

  • void *ptr 读的内容放的位置指针,
  • size_t size 读取得块大小
  • size_t n读取的个数,
  • FILE *fp 读取的文件指针

size_t fwrite(const void *ptr, size_t size, size_t n, FILE *fp);(将const void *ptr写入FILE *fp)

  • const void *ptr 写的文件内容的位置指针,
  • size_t size 写的块大小
  • size_t n 写的的个数
  • FILE *fp 要写文件指针
  • 成功返回读写的对象个数;出错时返回EOF
  • 既可以读写文本文件,也可以读写数据文件
  • 效率高

文件写完之后,文件指针指向文件末尾,如果这时候读,读不出内容;
解决方法:移动指针;关闭文件,重新打开

5.流的刷新和定位

5.1.刷新流

int fflush(FILE *fp);

  • 成功时返回0;出错时返回EOF
  • 将流缓冲区中的数据写入实际的文件
  • Linux下只能刷新输出缓冲区,输入缓冲区丢弃
  • 如果输出到屏幕使用fflush(stdout)
5.2.定位流

long ftell(FILE stream);

  • ftell() 成功时返回流的当前读写位置,出错时返回EOF

long fseek(FILE stream, long offset, int whence);

  • fseek()定位一个流,成功时返回0,出错时返回EOF
  • whence参数:SEEK_SET/SEEK_CUR/SEEK_END
    • SEEK_SET:从距文件开头offset位移量为新的读写位置;
    • SEEK_CUR:以目前读写位置往后增加offset个位移量;
    • SEEK_END:将读写位置指向文件尾后再增加offset个位移量
  • offset参数:偏移量,可正可负
  • 打开 a 模式,fseek无效

void rewind(FILE stream);

  • rewind(fp)相当于fseek(fp,0,SEEK_SET);
  • rewind()将流定位到文件开始位置
  • 读写流时,当前读写位置自动后移

这三个函数只适用于2G以下文件

获取文件大小

#include <stdio.h>

int main(int argc, const char *argv[])
{
    FILE *fp;

    if(argc < 2) {
        printf("usage: %s<file>\n",argv[0]);
        return -1; 
    }   
    if((fp = fopen(argv[1], "r")) == NULL) {
        perror("fail to open");
        return -1; 
    }   

    fseek(fp, 0, SEEK_END);

    printf("the size of %s is %ld\n", argv[1], ftell(fp));                           
    
    return 0;
}

6.格式化输入输出

printf系列
int printf(const char *format, …);
int fprintf(FILE *stream, const char *format, …);
int sprintf(char *str, const char *format, …);

  • 功能:printf()系列中的函数根据如下所述的格式产生输出:

    • printf()将输出默认写入标准输出流stdout(终端文件);
    • fprintf()将输出写入给定的输出流对应的文件中;
    • sprintf()将输出写入字符串str
  • 参数:

    • printf():

      • 参数1—const char * format一个字符串首地址。表示格式化字符串的地址
      • 参数…—可以有多个参数,根据格式化字符串来决定,表示要输出的数据(可以是变量名、常量、表达式)
    • fprintf():

      • 参数1—FILE * stream一个文件流指针。表示需要输出到的文件的信息结构体地址(输出到哪个文件中)]
      • 参数2—const char * format一个字符串首地址。表示格式化字符串的地址
      • 参数…—可以有多个参数,根据格式化字符串来决定,表示要输出的数据(可以是变量名、常量、表达式)
  • 返回值:int类型
    输出成功—返回打输出的字符数(不包括用于结束字符串输出的空字节)。
    输出失败—返回EOF,并设置errno来指示错误. #define EOF -1

  • 几个函数的特点:
    fprintf()可以向指定文件写入数据,包括终端标准输出(stdout)
    printf()默认只能给终端文件(stdout)写数据.stdout是行缓存

scanf系列

int scanf(const char *format, …);
int fscanf(FILE *stream, const char *format, …);
int sscanf(const char *str, const char *format, …);

  • 功能:格式化扫描输入

    • scanf()默认从终端标准输入(stdin)中格式化读取数据输入到程序中
    • fscanf()从文件流指针所指向的文件中格式化读取数据输入到程序中
    • sscanf()从字符串中格式化读取数据输入到程序中
  • 参数:
    scanf():

    • 参数1—const char * format一个字符串首地址。表示格式化字符串的地址
    • 参数…—可以有多个参数,根据格式化字符串来决定,表示将格式化读取的数据输入到程序中的地址。(程序中变量的地址)

    fscan():

    • 参数1—FILE * stream一个文件流指针。表示需要读取的文件的信息结构体地址(读取哪个文件)
    • 参数2—const char * format一个字符串首地址。表示格式化字符串的地址
    • 参数…—可以有多个参数,根据格式化字符串来决定,表示要格式化读取的数据要输入到程序中的地址(程序中变量的地址)
  • 返回值:int类型
    如果成功,这些函数返回成功匹配和分配的输入数据的数量
    如果失败:返回EOF。以下是错误的类型:
    1.成功匹配完之前只要有一处与格式化字符串不匹配的地方,则返回值EOF。
    2.如果发生读取错误,也会返回EOF

  • 特点:
    scanf函数系列遇到换行符’\n’和空格符’ '都会停止匹配。

7.练习

1.在程序中分别打开源文件和目标文件,循环从源文件中读取内容并写入目标文件。

#include <stdio.h>                                                              
#include <string.h>
#include <errno.h>

#define N 128

int main(int argc, const char *argv[])
{
    int n;
    int buf[N];
    FILE *fps, *fpd;

    if(argc < 3){
        printf("Usage:%s <src_file> <dst_file>\n",argv[0]);
        return -1;
    }

    //打开源文件
    fps = fopen(argv[1], "r");
    if(fps == NULL){
        fprintf(stderr, "fail to fopen %s: %s\n", argv[1], strerror(errno));
        return -1;
    }

    //打开目标文件
    fpd = fopen(argv[2], "w");
    if(fpd == NULL){
        fprintf(stderr, "fail to fopen %s: %s\n", argv[2], strerror(errno));
        return -1;
    }

    //循环读写文件
    n = fread(buf, 1, N, fps);
    if(n != EOF)
        fwrite(buf, 1, n, fpd);

    //关闭文件
    fclose(fps);
    fclose(fpd);

    return 0;
}

2.获取系统时间并保存到文件

  • time()用来获取系统时间(秒数)
    time_t time(time_t *seconds) 1970.1.1 0:0:0
  • localtime()将系统时间转换成本地时间
struct tm *localtime(const time_t *timer)
struct tm {
   int tm_sec;         /* 秒,范围从 0 到 59 */
   int tm_min;         /* 分,范围从 0 到 59 */
   int tm_hour;        /* 小时,范围从 0 到 23 */
   int tm_mday;        /* 一月中的第几天,范围从 1 到 31*/
   int tm_mon;         /* 月份,范围从 0 到 11 */
   int tm_year;        /* 自 1900 起的年数*/
   int tm_wday;        /* 一周中的第几天,范围从 0 到 6 */
   int tm_yday;        /* 一年中的第几天,范围从 0 到 365 */
   int tm_isdst;       /* 夏令时 */    
};
注意:
   int tm_mon;        获取的值要加1是正确的月份
   int tm_year;        获取的值加1900是正确的年份
  • 获取文件内的所有行数量:
   while(fgets(buf,32,fp)!=NULL){ 
          if(buf[strlen(buf)-1] =='\n'){  //注意判断是否是一行结束
               linecount++;
          }
	}

写完文件记得fflush ,写到磁盘里面去。
标准IO磁盘文件的缓冲区一般为4096
注意和标准输出的全缓冲区别,标准输出是1024

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <time.h>

int main(int argc, const char *argv[])
{
    FILE *fp;
    time_t ctime;
    struct tm *ctimestr;
    int linecount = 0;
    char buf[32] = {0};

    fp = fopen("time.txt", "a+");
    if(fp == NULL){
        perror("fopen");
        return -1;
    }

    while(fgets(buf, 32, fp) != NULL){
        if(buf[strlen(buf) - 1] == '\n')
            linecount++;
    }                                                                           
    
    while(1){
        ctime = time(NULL);
        ctimestr = localtime(&ctime);

        fprintf(fp, "%d: %04d-%02d-%-2d %02d:%02d:%02d\n",linecount,
                ctimestr->tm_year+1900, ctimestr->tm_mon+1, ctimestr->tm_mday,
                ctimestr->tm_hour, ctimestr->tm_min, ctimestr->tm_sec);

        fflush(fp);
        linecount++;
        sleep(1);
    }

    fclose(fp);

    return 0;
}
./time
time.txt:
0: 2022-08-20 09:24:25                                                          
1: 2022-08-20 09:24:26
2: 2022-08-20 09:24:27
3: 2022-08-20 09:24:28
4: 2022-08-20 09:24:29
5: 2022-08-20 09:24:30
6: 2022-08-20 09:24:31
7: 2022-08-20 09:24:32                         

二、文件IO

2.1.概述

文件IO,又称系统IO,系统调用。是操作系统提供的API接口函数
POSIX(可移植操作系统接口)定义的一组函数
文件IO不提供缓冲机制
标准IO和文件IO不能混用

功能标准IO文件IO(低级)
打开fopen、freopen、fdopenopen
关闭fcloseclose
getc,fgetc,getchar,fgets,gets,freadread
putc,fputc,putchar,fputs,puts,fwritewrite

文件描述符

  • 每个打开的文件都对应着一个文件描述符
  • 文件描述符是一个非负整数,linux为每一个打开的文件分配一个文件描述符
  • 文件描述符从0开始分配,依次递增
  • 文件IO操作通过文件描述符来完成
  • fd(fail descriptor)
  • 0-1023,表示文件
  • 0,1,2的含义 标准输入、标准数出、标准错误

2.2.文件IO编程

1.文件IO的打开

#include <fcntl.h>
int open(const char *pathname, int flags); 不创建文件
int open(const char *pathname, int flags, mode_t mode); 创建文件,不能创建设备文件

  • 成功时返回文件描述符;
  • 出错时返回EOF
  • 打开文件时使用两个参数
  • 创建文件时使用三个参数,指定新文件的权限
  • 只能打开设备文件

在这里插入图片描述

mode权限描述
S_IRWXU00700用户(文件所有者)具有读、写和执行权限
S_IRUSR00400用户具有读权限
S_IWUSR00200用户具有写权限
S_IXUSR00100用户具有执行权限
S_IRWXG00070同组用户具有读、写和执行权限
S_IRGRP00040同组用户具有读权限
S_IWGRP00020同组用户具有写权限
S_IXGRP00010同组用户具有执行权限
S_IRWXO00007其他用户具有读、写和执行权限
S_IROTH00004其他用户具有读权限
S_IWOTH00002其他用户有写权限
S_IXOTH00001其他用户有执行权限

文件IO和标准IO的模式对应关系
在这里插入图片描述
0664—普通用户权限

2.文件IO的关闭

#include <unistd.h>
int close(int fd);

成功时返回0;出错时返回EOF
程序结束时自动关闭所有打开的文件
文件关闭后,文件描述符不再代表文件

3.文件IO的读写

read函数用来从文件中读取数据
#include <unistd.h>
ssize_t read(int fd, void *buf, size_t count);

成功时返回实际读取的字节数;出错时返回EOF
读到文件末尾时返回0
buf是接收数据的缓冲区
count不应超过buf大小

write函数用来向文件写入数据:
#include <unistd.h>
ssize_t write(int fd, void *buf, size_t count);

成功时返回实际写入的字节数;出错时返回EOF
buf是发送数据的缓冲区
count不应超过buf大小

4.文件IO的定位

lseek函数用来定位文件:
#include <unistd.h>
off_t lseek(int fd, off_t offset, intt whence);

  • 成功时返回当前的文件读写位置;出错时返回EOF
  • whence参数:SEEK_SET/SEEK_CUR/SEEK_END
    • SEEK_SET:从距文件开头offset位移量为新的读写位置;
    • SEEK_CUR:以目前读写位置往后增加offset个位移量;
    • SEEK_END:将读写位置指向文件尾后再增加offset个位移量
  • offset参数:偏移量,可正可负

示例

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

int main(int argc, const char *argv[])
{
    int fd, ret;
    char buf[32] = "hello world";
    char buf2[32] = {0};

    fd = open("test.txt", O_RDWR | O_CREAT|O_APPEND, 0666);                                                       
    if(fd < 0) {
        perror("file to open");
        return 0;
    }   

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

    ret = write(fd, buf, strlen(buf));
    if(ret < 0) {
        perror("fail to write");
        return 0;
    }   

    printf("write count = %d\n", ret);

    lseek(fd, 0, SEEK_SET);

    ret = read(fd, buf2, 32);
    if(ret < 0) {
        perror("read");
        return 0;
    }   

    buf2[31] = 0;
    printf("read buf2 = %s\n", buf2);

    return 0;
}
//运行结果
linux@linux:~/Desktop/fileIO$ ./a.out
success,fd = 3
write count = 11
read buf2 = hello world
linux@linux:~/Desktop/fileIO$ cat test.txt 
hello world

5.访问目录

opendir函数用来打开一个目录文件:
#include <dirent.h>
DIR *opendir(const char *name);
DIR *fdopendir(int fd); 使用文件描述符,要配合open函数使用、

DIR是用来描述一个打开的目录文件的结构体类型
成功时返回目录流指针;出错时返回NULL

readdir函数用来读取目录流中的内容:
#include <dirent.h>
struct dirent *readdir(DIR *dirp);

struct dirent是用来描述目录流中一个目录项的结构体类型
成功时返回目录流dirp中下一个目录项;
出错或到末尾时时返回NULL
示例

#include <dirent.h>
#include <stdio.h>

int main(int argc, const char *argv[])
{
    DIR *dp;
    struct dirent *dt;

    dp = opendir("/home/linux/Desktop");                                             
    if(dp < 0) {
        perror("fail to opendir");
        return -1; 
    }   

    while((dt = readdir(dp)) != NULL) {
        printf("%s\n", dt->d_name);
    }   

    closedir(dp);
    return 0;
}

6.修改文件访问权限

chmod/fchmod函数用来修改文件的访问权限:
#include <sys/stat.h>
int chmod(const char *path, mode_t mode);
int fchmod(int fd, mode_t mode);

成功时返回0;出错时返回EOF
root和文件所有者能修改文件的访问权限
示例: chmod(“test.txt”, 0666);

7.获取文件属性

#include <sys/stat.h>
int stat(const char *path, struct stat *buf); 提供文件名字,获取文件对应属性
int lstat(const char *path, struct stat *buf); 获取的是链接文件的属性
int fstat(int fd, struct stat *buf); 通过文件描述符获取文件对应的属性
成功时返回0;出错时返回EOF
函数都是获取文件(普通文件,目录,管道,socket,字符,块()的属性

struct stat是存放文件属性的结构体类型:
	mode_t  st_mode;类型和访问权限
	uid_t  st_uid;所有者id
	uid_t  st_gid;用户组id
	off_t  st_size;文件大小
	time_t  st_mtime;  最后修改时间

 - stat结构体

struct stat {
    dev_t         st_dev;       //文件的设备编号
    ino_t         st_ino;       //节点
    mode_t        st_mode;      //文件的类型和存取的权限
    nlink_t       st_nlink;     //连到该文件的硬连接数目,刚建立的文件值为1
    uid_t         st_uid;       //用户ID
    gid_t         st_gid;       //组ID
    dev_t         st_rdev;      //(设备类型)若此文件为设备文件,则为其设备编号
    off_t         st_size;      //文件字节数(文件大小)
    unsigned long st_blksize;   //块大小(文件系统的I/O 缓冲区大小)
    unsigned long st_blocks;    //块数
    time_t        st_atime;     //最后一次访问时间
    time_t        st_mtime;     //最后一次修改时间
    time_t        st_ctime;     //最后一次改变时间(指属性)
};

 - 文件类型ST_mode

通过系统提供的宏来判断文件类型:
S_IFMT                     0170000    文件类型的位遮罩
S_ISREG(st_mode)           0100000    是否常规文件
S_ISDIR(st_mode)           0040000    是否目录
S_ISCHR(st_mode)           0020000    是否字符设备
S_ISBLK(st_mode)           0060000    是否块设备
S_ISFIFO(st_mode)          0010000    是否FIFO文件
S_ISLNK(st_mode)           0120000    是否链接文件
S_ISSOCK(st_mode)          0140000    是否SOCKET文件

 - 文件访问权限ST_mode

通过系统提供的宏来获取文件访问权限:               
S_IRUSR           00400                   bit:8    所有者有读权限
S_IWUSR          00200                        7    所有者拥有写权限
S_IXUSR           00100                       6    所有者拥有执行权限
S_IRGRP           00040                       5   群组拥有读权限
S_IWGRP          00020                        4   群组拥有写权限
S_IXGRP           00010                       3   群组拥有执行权限
S_IROTH           00004                       2   其他用户拥有读权限
S_IWOTH          00002                        1   其他用户拥有写权限
S_IXOTH           00001                       0   其他用户拥有执行权限

示例

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <time.h>

int main (int argc,char **argv){

   struct stat buf;
   int ret;
   ret = stat("chmod_t.c",&buf);
   if(ret<0){
      perror("stat");
      return 0;

   }
   if(S_ISREG(buf.st_mode)){
       printf("-");
   }
   if(S_ISDIR(buf.st_mode)){
       printf("d");
   }
   if(S_ISCHR(buf.st_mode)){
       printf("c");
   }
   if(S_ISBLK(buf.st_mode)){
       printf("b");
   }
   if(S_ISFIFO(buf.st_mode)){
       printf("p");
   }
   if(S_ISSOCK(buf.st_mode)){
       printf("s");
   }
   
//   printf(" ");
   int i;
   for(i=8;i>=0;i--){
       if(buf.st_mode & (1<<i)){
          switch(i%3){
          case 2:
              printf("r");
              break;
          case 1:
              printf("w");
              break;
          case 0:
              printf("x");
              break;
          }
       }else{
           printf("-");
       }
   }
   
   printf(" %d",(int)buf.st_size);

   struct tm *t;
   t = localtime(&buf.st_ctime);
   printf(" %d-%d-%d %d:%d",t->tm_year+1900,t->tm_mon+1,t->tm_mday,t->tm_hour,t->tm_min);

   printf(" chmod_t.c\n");  
}
//运行结果
linux@linux:~/Desktop/fileIO$ gcc stat.c 
linux@linux:~/Desktop/fileIO$ ./a.out
_ rw-rw-r-- 185 2022 8 16 13:15 chmod.c
linux@linux:~/Desktop/fileIO$ ls -l chmod.c 
-rw-rw-r-- 1 linux linux 185 Aug 16 13:15 chmod.c
linux@linux:~/Desktop/fileIO$ 
  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Linux实验二文件I/O操作是指在Linux系统中进行文件读写操作的实验。该实验主要涉及到文件的打开、读取、写入、关闭等操作,以及文件描述符、文件指针、文件权限等相关概念的理解和应用。通过该实验,可以深入了解Linux系统中文件I/O的底层实现原理,掌握文件操作的基本技能,为后续的Linux系统编程打下坚实的基础。 ### 回答2: 首先,Linux实验二文件I/O操作是操作系统学习中的一项基础实验,并且也是相对简单的实验之一。在此实验中,我们需要学习并掌握如何在Linux系统中使用文件读取(input)和文件写入(output)操作。 文件读取操作用于从存储设备中读取数据,主要包括打开文件、读取文件以及关闭文件等步骤。实现文件读取的相关函数有:open()、read()、close()等。 首先,使用open()函数打开一个文件,该函数返回一个文件描述符(一个非负整数),表示已打开文件的引用。然后,使用read()函数从文件中读取指定长度的数据,如果读取成功,则read()函数返回读取的字节数,否则返回-1。最后,使用close()函数关闭文件描述符。 文件写入操作也很简单,它用于将数据写入到文件中。实现文件写入的相关函数有:open()、write()、close()等。 使用open()函数打开一个文件,然后使用write()函数向该文件中写入数据,并将其保存在内存缓冲区中。如果写入成功,则write()函数返回写入的字节数,否则返回-1。最后,使用close()函数关闭文件描述符。 总的来说,文件I/O操作是一种在Linux系统中处理文件的常用方式,常用于读取或写入数据。在应用编程中,熟练掌握文件I/O操作非常重要,因为它涉及到数据的输入和输出。掌握这些操作可以使程序更有效地处理数据,提高代码质量和效率。 ### 回答3: Linux实验二的文件I/O操作是指在Linux系统中对文件进行读取、写入、修改等操作的过程。目的是让学生通过实践掌握Linux文件系统的基本操作,了解系统中文件的存储结构、读写权限等相关知识,提高操作系统理论知识的实用性和操作技能。 在Linux系统中,文件I/O操作主要涉及到三种函数:open、read 和write。open函数是用来打开一个文件的,当打开成功后,会返回一个文件描述符供后面使用;read函数是读取一个文件中的数据块;write函数是将数据块写入文件。也就是说,open函数用于文件的打开,read函数和write函数则用于文件的读入和写出。 在实验中,需要学生完成的任务是在Linux系统下通过命令行,使用open函数打开一个文件,然后通过read函数读取文件中的内容,最后使用write 函数将修改后的内容写回到文件中。可以通过学生自己编写程序,或者使用系统提供的一些工具来完成这个任务,如cat、vi、cp等等。 值得注意的是,在进行文件I/O操作时,需要对文件的权限进行认真的考虑,例如,文件的读写权限、文件所属用户和用户组等等。否则可能会导致无法读取或操作文件,甚至危及系统安全。因此,在进行实验前,学生必须要对Linux系统中的文件权限机制进行认真的学习和理解。 总之,文件I/O操作是Linux系统中非常重要的一部分,对于学生掌握Linux操作系统的理论知识和实际操作技能都具有重要的意义。在进行实验时,需要特别注意安全性和文件权限的问题。通过实验的学习,可以更好地理解文件I/O操作的原理和基本技巧,为今后的Linux开发和系统管理工作打下坚实基础。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值