Linux系统编程——William的技术进阶之路

本文详细介绍了Linux系统编程中的文件操作,包括文件的打开、关闭、创建及读写,深入探讨了open、close、read、write等API的使用。此外,文章还涵盖了进程的相关概念,如进程和程序的区别、进程创建(fork)、进程结束,以及进程间通信(IPC)的多种方式,如管道、消息队列、共享内存和信号量,最后涉及了线程的创建、同步与通信。
摘要由CSDN通过智能技术生成

一.文件编程

1.文件的打开、关闭与创建

1.1 相关Linux API

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

       int open(const char *pathname, int flags);
       int open(const char *pathname, int flags, mode_t mode);
       int close(int fd);
       int creat(const char *pathname, mode_t mode);

其中:
1、char* pathname 是文件所在位置,一个字符串
2、flag 主要有以下主要的类型:

  1. O_RDONLY 只读
  2. O_WRONLY 只写
  3. O_RDWR 可读可写
  4. O_CREAT 创建一个文件
  5. O_EXCL 若文件存在,则报错
  6. O_APPEND 对文件的写操作时,新内容写在原数据后面
  7. O_TRUNC 对文件的写操作时,把原内容删除,再写

3、mode表示O_CREAT创建文件时新文件的权限
读-4 写-2 执行-1

举个例子:
0600 可读可写
0400 可读不可写
0200 可写不可读

返回值:open函数读取成功:返回正数,错误为-1;

1.2 文件的打开与关闭

1.2.1 普通open
int open(const char *pathname, int flags);

举个例子:

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
int main()
{
   
        int fd;
        fd=open("./file1",O_RDWR);
        printf("fd=%d\n",fd);
        return 0;
}


当前目录:

CLC@Embed_Learn:~/Linux_review/File_programming$ ls
a.out  demo1.c  file1

运行结果(打开成功):

CLC@Embed_Learn:~/Linux_review/File_programming$ ./a.out 
fd=3

运行结果(打开失败):

CLC@Embed_Learn:~/Linux_review/File_programming$ ls
a.out  demo1.c
CLC@Embed_Learn:~/Linux_review/File_programming$ ./a.out 
fd=-1
1.2.2 有权限的open
int open(const char *pathname, int flags, mode_t mode);

举个例子:

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
int main()
{
   
        int fd;
        fd=open("./file1",O_RDWR,0600);
        printf("fd=%d\n",fd);
        return 0;
}

当前目录:

CLC@Embed_Learn:~/Linux_review/File_programming$ ls
a.out  demo1.c  demo2.c file1

运行结果(打开成功):

CLC@Embed_Learn:~/Linux_review/File_programming$ ./a.out 
fd=3

运行结果(打开失败):

CLC@Embed_Learn:~/Linux_review/File_programming$ ls
a.out  demo1.c demo2.c
CLC@Embed_Learn:~/Linux_review/File_programming$ ./a.out 
fd=-1
1.2.3 close函数
close(fd);

1.3 文件的创建

1.3.1 以带权限的open函数实现
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
int main()
{
   
        int fd;
        fd=open("./file1",O_RDWR,0600);

        if(fd ==-1)
        {
   
                printf("open failed!\n");
                open("./file1",O_RDWR|O_CREAT,0600);
                printf("create success!\n");
        }
        //printf("fd=%d\n",fd);
        return 0;
}

程序执行前:(没有file1)

CLC@Embed_Learn:~/Linux_review/File_programming$ ls
a.out  demo1.c  demo2.c

程序执行后:(生成了file1)

CLC@Embed_Learn:~/Linux_review/File_programming$ ls
a.out  demo1.c  demo2.c  file1
1.3.2 以creat函数实现
 int creat(const char *pathname, mode_t mode);

举个例子:

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
int main()
{
   
        creat("./createFile",0600);
        return 0;
}

程序执行前:(没有creatFile)

CLC@Embed_Learn:~/Linux_review/File_programming$ ls
a.out  demo1.c  demo2.c  demo3.c  file1

程序执行后:(生成了creatFile)

CLC@Embed_Learn:~/Linux_review/File_programming$ ls
a.out  createFile  demo1.c  demo2.c  demo3.c  file1

查看一下权限:

CLC@Embed_Learn:~/Linux_review/File_programming$ ls -l
total 24
-rwxr-xr-x 1 CLC book 8378 Sep 14 23:11 a.out
-rw------- 1 CLC book    0 Sep 14 23:13 createFile
-rw-r--r-- 1 CLC book  342 Sep 14 22:31 demo1.c
-rw-r--r-- 1 CLC book  467 Sep 14 22:56 demo2.c
-rw-r--r-- 1 CLC book  311 Sep 14 23:13 demo3.c
-rw------- 1 CLC book    0 Sep 14 22:58 file1

createFile 的权限为-rw 可读可写 印证了0600

2.文件的读写

2.1 相关Linux API

       #include <unistd.h>
		//读:
       ssize_t read(int fd, void *buf, size_t count);
		//写:
	ssize_t write(int fd, const void *buf, size_t count);

其中:

  1. fd 代表文件描述符
  2. buf 字符串缓存
  3. count 需要读、写的字节数量
  4. 返回值:成功为读、写的字节个数,失败为-1

2.2 文件的读取 read

ssize_t read(int fd, void *buf, size_t count);

举个例子:

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
int main()
{
   
        char* buf;
        buf=(char*)malloc(128);
        int fd;
        fd=open("./TestFile",O_RDWR|O_CREAT,0600);
        read(fd,buf,128);

        printf("buf=%s\n",buf);
        return 0;
}

TestFile的内容:

123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
~                                                                                                     
~                                                                                                     
                                                                                                    
"TestFile" 1L, 121C  

读出来的结果:

CLC@Embed_Learn:~/Linux_review/File_programming$ ./a.out 
buf=123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890

2.3 文件的写入 write

ssize_t write(int fd, const void *buf, size_t count);

举个例子:

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

int main()
{
   
        char* buf="William is handsome";
        int fd;
        fd=open("./TestFile2",O_RDWR|O_CREAT,0600);
        printf("open success!fd=%d\n",fd);
        write(fd,buf,strlen(buf));
        close(fd);

        return 0;
}

TestFile2的内容:

William is handsome                                                                                                
~                                                                                                     
~                                                                                                     
~                                                                                                     
~                                                                                                     
~                                                                                                     
"TestFile2" 1L, 20C 

2.4 文件的读写

将上述二者结合一下:

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

int main()
{
   
        char* buf="William is handsome";
        char* readBuf;
        readBuf=(char*)malloc(sizeof(buf));

        int fd;
        fd=open("./TestFile2",O_RDWR|O_CREAT,0600);
        printf("open success!fd=%d\n",fd);
        int n_write=write(fd,buf,strlen(buf));
        
        read(fd,readBuf,n_write);
        printf("readBuf=%s\n",readBuf);
        close(fd);

        return 0;
}

发现啥都输出不了:

CLC@Embed_Learn:~/Linux_review/File_programming$ ./a.out 
open success!fd=3
readBuf=

原来是光标的问题,write完了以后文件光标就在EOF了,所以我们有两种解决方案:

2.4.1 重新打开文件
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{
   
        char* buf="William is handsome";
        char* readBuf;
        readBuf=(char*)malloc(sizeof(buf));
        int fd;
        
        fd=open("./TestFile2",O_RDWR|O_CREAT,0600);
        int n_write=write(fd,buf,strlen(buf));
        close(fd);
        
 		fd=open("./TestFile2",O_RDWR|O_CREAT,0600);
        read(fd,readBuf,n_write);
        printf("readBuf=%s\n",readBuf);
        close(fd);

        return 0;
}

可以执行了:

CLC@Embed_Learn:~/Linux_review/File_programming$ ./a.out 
open success!fd=3
readBuf=William is handsome

2.4.2 光标移动 lseek

光标移动需要lseek函数:

       #include <sys/types.h>
       #include <unistd.h>

       off_t lseek(int fd, off_t offset, int whence);

其中:

  1. fd 是文件描述符
  2. offset是偏移量
  3. whence主要有以下几种宏:

SEEK_SET 文件开头
SEEK_CUR 当前光标位置
SEEK_END 文件结尾

返回值:成功返回offset 失败返回-1

解决上述问题:

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

int main()
{
   
char* buf="William is handsome";
        char* readBuf;
        readBuf=(char*)malloc(sizeof(buf));

        int fd;
        fd=open("./TestFile2",O_RDWR|O_CREAT,0600);
        printf("open success!fd=%d\n",fd);
        int n_write=write(fd,buf,strlen(buf));

        lseek(fd,0,SEEK_SET);

        read(fd,readBuf,n_write);
        printf("readBuf=%s\n",readBuf);
        close(fd);
}

也能成功:

CLC@Embed_Learn:~/Linux_review/File_programming$ ./a.out 
open success!fd=3
readBuf=William is handsome
2.4.3 小妙招:计算文件大小

利用lseek函数可以计算文件大小:

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

int main()
{
   
        int fd=open("./TestFile2",O_RDWR|O_CREAT,0600);
        printf("open success!fd=%d\n",fd);

        int size=lseek(fd,0,SEEK_END);
        
        printf("size of file is=%d\n",size);
        close(fd);
        return 0;
}

CLC@Embed_Learn:~/Linux_review/File_programming$ ./a.out 
open success!fd=3
size of file is=20
CLC@Embed_Learn:~/Linux_review/File_programming$ ls -l
-rw------- 1 CLC book   20 Sep 15 23:51 TestFile2

3.文件的操作

3.1 文件的一些补充概念

3.1.1 系统默认文件描述符

fd=0 :标准输入
fd=1 :标准输出
fd=2 :标准错误

3.1.2 静态文件与动态文件

静态文件:在磁盘里存着的文件
动态文件:被打开的文件

3.1.3 为什么要close?

在文件被打开后,是动态的,进行修改之后,需要使用close进行写入

3.2 小项目 自制cp命令

3.2.1 主函数的一些补充

为了在shell中可以对程序进行传参,这里引入main函数的完整写法:

#include <stdio.h>
int main(int argc,char** argv)
{
   

}

其中:

  1. argc: 传参的数量
  2. argv: 传的参数
3.2.2 自制cp代码
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

int main(int argc,char** argv)
{
   
	if(argc!=3)
	{
   
		printf("error!");
		exit(-1);
	}
		
	
	int fd=open(argv[1],O_RDWR|O_CREAT,0600);
	int size=lseek(fd,0,SEEK_END);

	lseek(fd,0,SEEK_SET);

	char* buf;
	buf=(char*)malloc(sizeof(char)*size+8);
	read(fd,buf,size);

	int fd2=open(argv[2],O_RDWR|O_CREAT|O_TRUNC,0600);

	write(fd2,buf,size);

	
	close(fd);
	close(fd2);

	return 0;
}

尝试在shell下运行:

CLC@Embed_Learn:~/Linux_review/File_programming$ ./mycp demo1.c mycptest.c 

查看一下结果:

CLC@Embed_Learn:~/Linux_review/File_programming$ vimdiff demo1.c mycptest.c 

- #include <sys/types.h>                           |- #include <sys/types.h>
| #include <sys/stat.h>                            || #include <sys/stat.h>
| #include <fcntl.h>                               || #include <fcntl.h>
| #include <stdio.h>                               || #include <stdio.h>
| int main()                                       || int ma
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值