linux 学习day1

linux应用编程 (高级编程)
IO
多任务
网络

IO(文件) 

文件操作:
文本文件,mp3,jpeg,png ,mp4,avidoutd

文件:
    一组相关数据的有序集合
文件名:
    这组相关数据的一个名称

linux里面对文件的处理:
思想:
      一切皆文件 ,文件用来存储数据(数据、指令)
      
      everything is file!
      

b c d - l p s 

b -- block      -- 块设备文件   --- 硬盘(存储设备) 
c -- character  -- 字符设备文件 --- 鼠标 
d -- directory  -- 目录文件     
- -- regular    -- 普通文件 
l -- link       -- 软连接文件   --- 类似windows的快捷方式  
p -- pipe       -- 管道文件     --- 实现操作系统中 进程间的一些 信息交换(通信)
s -- socket     -- 套接字文件   --- 网络的时候 (进程间的通信)


【操作文件的基本思路及框架】//凡是文件,都可从这个思路出发进行思考
文件操作三步骤:
1.打开 
2.读写    
3.关闭 

Linux提供的两种文件操作方式:
文件编程:
1.标准IO --- 库函数  -------标准c库函数,
2.文件IO --- 系统调用-------Linux内核为用户提供的函数接口


系统调用:Linux内核为用户提供的函数接口
库函数:标准c库函数, 对Linux内核中系统调用的封装
    
    

标准IO库:
1.标准io的概念 
    1975 Dennis Ritchie编写, IO库,
    从C语言的标准,ANSI c 
    IO  input  output
    I: 键盘是标准输入设备 ====》默认输入就是指键盘  /dev/input
    O: 显示器是标准输出设备 ==》默认输出就是指显示器
    
    Linux操作系统当中IO都是对文件的操作
    C一部分,任何支持标准C的系统都可使用标准IO实现文件存储
    标准IO在UNIX上是对文件IO的封装
   
    一般都是对普通文件操作是一种有缓存的IO 在文件IO和用户程序之间,
    加入缓冲区,可以有效减少系统调用的次数,节省系统IO调度资源
    


2.功能:
  用来操作普通文件
      普通文件:
        1.ASCII码文件(代码、文本文件)
        2.二进制文件(音视频、图片)
        
        ASCII码文件是一种特殊的二进制文件
        
        2021
        '2' '0' 2' '1' 
        
        2021
        0000 0000 0000 0000 0000 0111 1110 0101


3.操作方法
    1.打开 -- fopen  //FILE open
    2.读写 --
              fgetc / fputc   读出、写入单个字符
              fgets / fputs   读出、写入一行字符
              fread / fwrite  读出、写入指定长度数据
    3.关闭 -- fclose          


    man手册
    标准man手册分为8个章节:
    man 1        用户命令
    man 2        系统调用
    man 3        c函数库调用
    man 4        设备文件和特殊文件
    man 5        配置文件和格式
    man 6        游戏相关
    man 7        杂项,总述
    man 8        管理类命令

4.API函数接口
 
    1.fopen
    #include <stdio.h>
    FILE* fopen(const char *path, const char *mode);
    功能:
         流打开函数 (打开文件,并关联到一个流)
    参数:
        @path --要打开的文件的文件名(字符串形式)
        @mode --打开文件的操作模式
            r ---打开文件做读操作
                 注意:
                 文件必须存在 
                 
            r+   打开文件做读写操作
                 注意:
                 文件必须存在
                 
            w    打开文件做写操作
                 注意:
                 如果文件已经存在,则会将文件清空为0
                 如果文件不存在,则会创建一个新文件。
                 
            w+  打开文件做读写操作
                 注意:
                 如果文件已经存在,则会将文件清空为0
                 如果文件不存在,则会创建一个新文件。

            a    打开文件做写操作
                 注意:
                 如果文件已经存在,则在文件末尾进行写入 
                 如果文件不存在,则会创建一个新文件。
                 
            a+   打开文件做读写操作
                 注意:
                 如果文件已经存在,则在文件末尾进行写入 
                 如果文件不存在,则会创建一个新文件。
            
            
    返回值:
       成功 FILE *  (文件流指针)
       失败 NULL 并且 设置 errno 表明错误原因 

       
    流:
        数据从文件当中流入和流出所体现出来的字节流叫做流

        FILE 结构定义的对象(FILE * 指向的对象)称之为流对象,FILE *叫文件流指针。


        标准IO将对文件的操作转换成了对"流"的操作。
        所以,标准IO的文件相关的函数都是围绕着 FILE进行的。
         
          FILE * fp 
          FILE * fp;//流指针------关联一个文件   
          FILE * 实际上是指向了一块内存空间(缓存,fileno)
          
          
          FILE *fp <->【FILE结构体[缓存,fileno]】//堆区(malloc)
 
    2.fclose
      int fclose(FILE *fp);
      功能:
        关闭文件流指针 
      参数:
        fp:文件流指针 
      返回值:
        成功返回0 
        失败返回EOF(-1)
        
      注意:fopen操作完毕后使用fclose关闭,否则会产生内存泄漏
           不要重复调用fclose 
 
 
 
 

    3.fputc
    int fputc(int c, FILE *stream);
    功能:
        向流中写入一个字符
    参数:
        c:要写入的字符
        stream:文件流指针
    返回值:
        成功返回 写入的字符ASCII码值
        失败返回 EOF

    练习:利用fputc实现在file.txt文件中写入hello world 

    
    //读 
    4.fgetc
    int  fgetc(FILE *stream);
    功能:
        从流中读取一个字符
    参数:
        stream:文件流指针
    返回值:
        成功返回读到字符的ASCII码值
        读到文件末尾 返回 EOF   
        失败返回EOF     EOF
        


 
    操作系统在运行一个程序时,会默认打开三个流:
        stdin        FILE*        标准输入流   ---->键盘
        stdout         FILE*        标准输出流   ---->屏幕
        stderr         FILE*        标准出错流   ---->屏幕
    
    gets scanf getchar ->  stdin 
    puts printf putchar -> stdout 
    perror -> stderr 
   

 
 
        

    
    如果输入q 表示输入结束!
    stdin --获取数据 --- fgetc  
    fp    --保存数据 --- fputc(ch,fp); // fp --- fopen     
 
    
            
    等价:
    ch = getchar();
    ch = fgetc(stdin);
    
    等价:
    putchar(ch);
    fputc(ch, stdout);


    


//注意点:
fgetc()函数的结束判断。
1、EOF 宏来判断 ===》系统预制的文件结束标记
end of file  -1

c = fgetc(fp);
   if(EOF == c) ///file end;
   if(!feof(fp))
   
   while(1)
   {
        c=fgetc(fp);
        if(feof(fp))
           break;    
   }
2、feof() 函数判断到文件末尾  // ferror()
int feof(FILE *stream);
功能:
      判断当前参数stream的文件流指针是否到达文件结尾。
      如果到达文件结尾则返回真,否则返回假
      注意:
      该操作一定要在一次IO操作之后判断(在一次读写操作后判断)。
参数:
      stream 要判断结尾的文件流对象
返回值:成功到达结尾是 真
        否则 是假
3.ferror() 
      int ferror(FILE *stream);
   功能:
        判断当前参数stream的文件流指针是否出错。
    参数:
         stream 要判断的文件流对象指针
    返回值:出错 真
           否则 假 
           

   


缺点:
    效率低下
    

    5.fputs
    int fputs(const char *s, FILE *stream);
    功能:
           向流中写入一行字符串       
    参数: s 
               要写的信息,一般是固定的字符串或者有数据的数组。
           stream 
               要写入的目标文件流对象

    返回值:成功 nonnegative number on success
            失败 -1;
        
    注:
        不写入 '\0' 
    
    puts和fputs的区别:
        1.fputs不会自动增减\n
        2.puts 会多打印\n字符

    6.fgets
    //按行读写   按字符串读写 
    fgets  -- char ---> string 
    fputs  -- char ---> string

    char *fgets(char *s, int size, FILE *stream);
    功能:
          从stream流对象关联的文件中获取size大小字节的文本数据
      并存储到s对应的本地内存(栈区数组,堆区内存)
          
    参数: s    要存储数据的本地内存(栈,堆)
    
           size 要获取的数据长度,单位字节。
           stream 要获取的目标文件流对象,

            可以是stdin ,程序会阻塞等待
            如果是普通文件fp 则指向文件第一行数据
    返回值:成功 返回指向有效数据的首地址,一般等于s的地址
            失败 或者 文件末尾 NULL;

        注意:
        1.fgets能读取一行就读取一行
        2.fgets会读到n个数据,如果n个数据中存在\n字符则立即停止当
          前的读取操作,如果没有\n,则读取n-1个字符,最后一个存储\0    
        3.fgets每行读取的数据后面都有一个\n,在\n后面存放一个\0
                     12345
            buf[] = '1''2''3''4''5''\n''0'

        4.gets是危险的,因为没有规范读到数据的上限              
        5.gets会去掉从终端读入的\n字符 //也读走了\n 但是将 \n 去掉了 \n --> '\0'
     





            
    
    
    ./a.out 
    1
    2
    3
    4 
    
    ./a.out 
    5
    6
    7
    8
    
    功能:
    1.统计原先有多少行数据!
      fgets(); //\n 
      行数 
    2.时间 
      time(); // 获取的一个秒数 1970.      
      localtime(); 
      struct tm *localtime(const time_t *timep);
      time_t time(time_t *t);
       

        

 
// 
 fflush();    
     #include <stdio.h>

       int fflush(FILE *stream);
       刷新指定的流文件 (刷新 ---写操作- 将缓存中的数据写到要达到的目标位置)

缓冲区 //缓存  ---怎么设计的?

//稍后说明 ---一组函数介绍完
行缓冲,1k, terminal,主要用于人机交互--- stdout ---终端
    缓存区满或者遇到\n刷新    1024
                行缓存多是关于终端的一些操作
                1.遇到 \n刷新
                2.缓存区满刷新
                3.程序结束刷新
                4.fflush刷新  fflush(stdout); //强制刷新 
                
全缓冲,4k,主要用于文件的读写 --- 普通文件的操作
    缓存区满刷新缓存区 4096
            对普通文件进行标准IO操作,建立
            的缓存一般为全缓存
            刷新条件:
                1.缓存区满刷新
                2.程序结束刷新
                3.fflush来刷新  fflush(fp);
                4.文件关闭刷新
                
                
无缓冲,0k  主要用于出错处理信息的输出 stderr 
    不对数据缓存直接刷新
    printf();==>>stdout 
    fprintf(strerr,"fopen error %s",filename);
                界面交互    出错处理


  


---------------------------------------------------      

    
二进制文件读写:  fread()/fwrite()
    
int a = 2 ;
vim -t size_t 
读:

size_t  fread(void  *ptr,  size_t size, size_t nmemb, FILE *stream);
功能:
      从指定的stream流对象中获取nmemeb个大小为size字节的数据块到ptr
      所在的本地内存中。
参数:
      ptr    要存储数据的本地内存一般是数组或者结构体指针
      size   单个数据块的元数据大小。最小单元的大小
      nmemb  要获取的数据块的个数,拷贝的数据块个数。
      stream 要获取数据的源文件流对象,如果是stdin表示从
      键盘获取数据,如果是fp文件则表示从普通文件获取。
返回值:
        成功 小于等于nemeb的整数,表示获取的数据长度
        失败 小于0,结尾 0;

写:
size_t fwrite(const void  *ptr,  size_t  size,size_t nmemb, FILE *stream);
功能:
      从ptr所在本地内存中取出nmemb个大小为size的数据块写入到stream流对应
      的文件流对象中。
参数:ptr 要写的数据块地址,一般是数组或者结构体指针
      size  要写的数据块元数据大小,单位是字节
      nmemb 要写的数据块的个数
      stream 要写的目标文件流对象。如果是stdout则表示数据会
      写到终端屏幕显示,如果是fp的普通文件则会写入到文件中。

返回值:成功 小于等于nmemb 的个数。
        失败 <0

    struct person
    {
        char name[20];
        int age;
        char sex;
        char addr[100];
    }; 
    
    //保存到一个文件中?
    //fwrite();
    
    
    person per;sizeof(per)


    
    
注:
  fread fwrite 往往都是 处理 ,数据格式相对固定的数据 
  
  struct {
      
  };


 


int a  =10;
        
        
练习:
1、使用fread和fwrite的方式完成用户输入信息并打印输出。 //一个输入,一个输出,遇到"exit" "quit"结束 

作业: //实现文件拷贝 
    使用fread和fwrite方式完成任意普通文件的拷贝功能。


//定位操作:
标准IO之文件定位函数:
fseek()   
ftell()  
rewind()

    1.fseek
    int fseek(FILE *stream, long offset, int whence);//long -->signed long 
    功能:
          将stream流文件中的文件指针
          从whence位置开始
          偏移offset字节的长度。
          
    参数:
          stream  要移动文件指针的目标文件流对象。 
               注意:不支持设备文件,一般用于普通文件。  
          offset  
                  要在文件内偏移的距离,单位字节。
                  如果值为整数,则向文件末尾偏移
                  如果值为负数,则向文件开头偏移
                  
          whence  偏移的起始位置,由系统定义的三个宏开始。
            SEEK_SET  文件的开头位置   offset 只能是正值 
            SEEK_CUR  文件的当前位置   offset 可正 可负 
                                       但是 
                                       如果当前位置与 SEEK_SET重合 offset 不能是负的 
                                       
            SEEK_END  文件的末尾位置   offset 可正 可负 
                                       正 --- 空洞文件 
                             
    返回值:    
        成功: 返回 0
        失败:  -1;
        eg:
        
        fseek(fp,100,SEEK_SET); //从头开始往后偏移100个字节 
        fseek(fp,-100,SEEK_SET);
        

如果从文件的指定位置向后偏移过程中已经超过了文件
的当前末尾位置,则会自动以'\0'来填充文件内容,从
而形成一种被称为"空洞文件" 的特殊文件。

产生空洞文件的操作:
1.进行偏移 
2.做一次写操作 
  fputc(0,fp);
  
  .downloading
  
用途:
   提前抢占磁盘空间
  

//获取文件大小:
     fseek(fp,0,SEEK_END);
     len = ftell(fp);
//定位到文件开头      
fseek(stream,0L,SEEK_SET); <==>rewind(fp);
//定位到文件尾部 
fseek(stream,0L,SEEK_END);


练习:
    获取文件大小

模拟迅雷下载:
       xxxx
          
       //1.获取源文件大小 
         
      //2. 在本地 创建 空洞文件 
     
      //3.复制文件 

     2.    ftell
        long ftell(FILE *stream);
        
        功能:获取文件位置指示器的偏移量
        参数:求偏移量的文件流指针
        返回值:文件位置指示器到文件开头的偏移字节数

     3. rewind(fp);
         void rewind(FILE *stream)
        功能:
             获取当前文件流指针的具体位置,
             一般以文件开头到当前指针的字节数为返回值。
             
        参数:stream 要返回指针距离的文件流对象
        返回值:void


rewind()  等效于:
fseek(stream,0L,SEEK_SET);


    2. 模拟迅雷下载:
               
           //1.获取源文件大小     
          //2. 在本地 创建 空洞文件          
        
          //3.复制文件 
      
      3.实现插入功能
      
          1.txt  
          往文件中,指定第n个字节后 插入一句话  ---- "i am xxx....\n"
          
          //定位到指定的位置 
          //将后面部分的数据挪走 ---- 
          malloc(len);
          
          //插入数据 
          再将保存的数据写到后面。
        
    
    
    fopen();
    fclose();
    
    fputc/fgetc
    fputs/fgets
    fwrite/fread
    
    fseek,
    ftell,
    rewind,
    

格式化输入输出(IO):
   
    1.fprintf
    3.sprintf
    
       int printf(const char *format, ...);
       int fprintf(FILE *stream, const char *format, ...);
       功能:将格式化的字符串写入文件
       int sprintf(char *str, const char *format, ...);
       功能:将格式化的字符串写入数组
     
     
字符串分割函数:
     strtok
     
     

   
   

    
 

  • 10
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值