I/O进线程

1、标准I/O

1.1 定义

以ANSIC为标准,在系统调用之上封装的接口库,
为io操作底层的系统调用提供一个通用接口。

1.2 文件指针

FILE指针, 
每一个被操作的文件都在内存中开辟一个区域,
用来存储文件的相关信息, 该空间的类型为结构体类型,
名字为FILE。

标准io库的所有操作都是围绕流(stream)来进行的, 在标准io中 FILE *表示。

1.3 刷新缓存

int fflush(FILE *stream);

1.4 更改缓存类型

void setbuf(FILE *stream, char *buf);
//将stream流缓存改成 用户自定义的buf缓存

1.5 Linux中打开一个终端时, 系统默认打开三个文件

标准输入			stdin 		0
标准输出			stdout 		1
标准错误输出		stderr		2

1.6 文件操作流程

// 1. 打开(创建打开)
FILE * fopen(const char * path, const char *mode);
	/*功能:
		打开(创建打开)
	  参数:
	  	path ---> 待操作的文件名(可包含路径)
	  	mode ---> 文件打开方式(r/w/a)
	  返回值:
	  	成功:	文件指针
	  	失败:	NULL, 并设置errno
	*/

// 2. 数据读写
	// 2.1 将数据format 格式输出到 指定的stream流中
	int fprintf(FILE *stream, const char *format, ...);
	//扩展:
			//1. 将数据按照format格式输出到buf地址上
			int sprintf(char *buf, const char *format, ...)
			//2. 将buf地址上的数据, 按照format格式, 赋值给后面的变量
			int sscanf(const char *buf, const char *format, ...)
	// 2.2 
	
//3. 关闭

作业:

// 1. 计算缓冲区大小

#include<stdio.h>
#include<strings.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>

int main(int argc, char * argv[])
{
	FILE *fp = fopen("1.txt", "w+");

#if 0
	//行缓存
	int count = 0;
	char buf[1024] = "a";
	while(1)
	{
		fwrite(buf, sizeof(buf), 1, stdout);
		count++;
		fprintf(fp, "%d ", count);
		fflush(fp);
		sleep(1);
	}

#else
	// 全缓存
	fputc('a', fp);
	printf("%ld \n", fp->_IO_buf_end - fp->_IO_buf_base);

	printf("%d\n", BUFSIZ);
#endif

	fclose(fp);
	return 0;
}

// 2. 统计当前终端最大可以打开文件个数

#include<stdio.h>
#include<strings.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>

int main(int argc, char * argv[])
{
	int count = 0;
	while(1)
	{
		FILE *fp = fopen("file.txt", "w");
		if(fp == NULL)
			break;
		count++;
	}
	printf("%d \n", count);

	return 0;
}

// 3. 使用标准IO,实现不同路径的文件的拷贝(fgetc/fgets/fread)。

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

int main(int argc, char * argv[])
{
	if(argc < 3)
	{
		printf("need 3 arguements\n");
		return -1;
	}

	FILE *fp = fopen(argv[1], "r");
	if(fp == NULL)
	{
		perror("fopen");
		return -1;
	}

	FILE *fp1 = fopen(argv[2], "w+");
	if(fp1 == NULL)
	{
		perror("fopen");
		return -1;
	}
#if 0
	while(!feof(fp))
	{
		fputc(fgetc(fp), fp1);
	}
#else
	char buf[128] = {0};
	while(fgets(buf, sizeof(buf), fp) != NULL)
	{
		fputs(buf, fp1);
	}
#endif

	fclose(fp);
	fclose(fp1);

	return 0;
}

/* 4. 编程读写一个文件test.txt,每隔1秒向文件中写入一行数据,
		类似这样: 
		1,  2007-7-30 15:16:42  
		2,  2007-7-30 15:16:43
		该程序应该无限循环,直到按Ctrl-C中断程序。
		再次启动程序写文件时可以追加到原文件之后,并且序号能够接续上次的序号,比如: 
		1,  2007-7-30 15:16:42
		2,  2007-7-30 15:16:43
		3,  2007-7-30 15:19:02
		4,  2007-7-30 15:19:03
		5,  2007-7-30 15:19:04
*/

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

void loop(int i, FILE *fp);
int main(int argc, char * argv[])
{
	int i = 1;
	char buf[50];

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

	int ch = fgetc(fp);

	if(ch == EOF)
	{
		i = 1;
		loop(i, fp);
	}
	else
	{
		i = 0;
		while(!feof(fp))
		{
			fgets(buf, sizeof(buf), fp);
			i++;
		}
		loop(i, fp);
	}

	fclose(fp);

	return 0;
}

void loop(int i, FILE *fp)
{
	time_t curtime;
	struct tm *t;

	while(1)
	{
		curtime = time((time_t *)NULL);
		t = localtime(&curtime);
		fprintf(fp, "%d,  %4d-%02d-%02d %02d:%02d:%02d\n", i++, t->tm_year+1900, t->tm_mon+1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
		fflush(fp);
		sleep(1);
	}
}

2、文件I/O

作业

// 1. 实现ls -l功能
#include<stdio.h>
#include<strings.h>
#include<stdlib.h>
#include<string.h>

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

#define PATH "file.txt"

int main(int argc, char * argv[])
{
	struct stat st;
	struct group *gp;

	//获取某个文件的属性
	if(stat(PATH, &st) < 0)
	{
		perror("stat");
		return -1;
	}

#if 0
	if(S_ISREG(st.st_mode))
	{
		printf("-\n");
	}
	else if(S_ISDIR(st.st_mode))
	{
		printf("d\n");
	}
#else
	switch(st.st_mode & S_IFMT){
		case S_IFREG:
			printf("-"); break;
		case S_IFDIR:
			printf("d"); break;
		case S_IFCHR:
			printf("c"); break;
		case S_IFBLK:
			printf("b"); break;
		case S_IFIFO:
			printf("p"); break;
		case S_IFLNK:
			printf("l"); break;
		case S_IFSOCK:
			printf("s"); break;
	}
#endif
#if 0
	switch(st.st_mode & S_IRWXU){
		case S_IRUSR:
			printf("r");
		case S_IWUSR:
			printf("w");
		case S_IXUSR:
			printf("x");
		default:
	}
#else
	int i;
	for(i = 8; i >= 0; i--){
		if(st.st_mode & (1 << i)){
			switch(i % 3){
				case 2:
					printf("r"); break;
				case 1:
					printf("w"); break;
				case 0:
					printf("x"); break;
			}
		} else {
			printf("-");
		}
	}
#endif
	printf(" ");

	printf("%ld", st.st_nlink);	//链接个数
	printf(" ");
	struct passwd *pa = getpwuid(st.st_uid);
	printf("%s", pa->pw_name);	// 文件或目录拥有者
	printf(" ");

	gp = getgrgid(st.st_gid);
	printf("%s", gp->gr_name);	// 文件或目录所属组
	printf(" ");
	printf("%ld", st.st_size);	// 文件或目录大小
	printf(" ");

	struct tm *info;
	info = localtime(&st.st_mtime);
	//文件或目录最后一次修改时间
	printf("%02d月 %02d日 %02d:%02d", info->tm_mon + 1, info->tm_mday, info->tm_hour, info->tm_min);
	printf(" ");
	//文件或目录名名
	printf("%s\n", PATH);

	return 0;
}

// 2. 使用文件io, 实现图片的拷贝。

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

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

int main(int argc, char * argv[])
{
	int fd = open("1.jpg", O_RDONLY);
	int fd1 = open("./2.jpg", O_RDWR | O_CREAT, 0640);
	if(fd == -1)
	{
		perror("open");
		return -1;
	}

	char *buf = (char *)malloc(1024*1024*15);
	int rd = 1, wd;

	while(rd)
	{
		rd = read(fd, buf, sizeof(buf));
		wd = write(fd1, buf, sizeof(buf));
	}

	close(fd);
	close(fd1);

	return 0;
}

3、进程

4、线程及线程间的通信

5、进程间通信

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值