码迷,mamicode.com
首页 > 系统相关 > 详细

Linux-(C)文件读写实例(系统调用/标准I/O库)

时间:2016-07-24 16:29:32      阅读:587      评论:0      收藏:0      [点我收藏+]

标签:

文件在Linux中是一个非常重要的概念,几乎一切都是文件(引用Linux程序设计/Beginning Linux ProGramming,那么这次主要学习文件读写。

1、系统调用跟库函数调用区别

从实现的角度:系统调用直接对文件和设备进行访问和控制的的一组底层接口, 而标准I/O库为地城I/O调用提供了一个通用的接口,系统调用直接跟底层打交道,系统调用移植性远不如标准I/O库好。

从性能的角度:使用系统调用会影响系统的性能。与库函数调用相比,系统调用的开销要大些,因为在执行系统调用时,Linux必须从运行用户代码切换到执行内核代码,然后再返回用户代码。减少这种开销的一个好办法是,在程序中尽量减少系统调用的次数,并且让每次系统调用完成尽可能多的工作。比如,每次读写大量的数据而不是每次仅读写一个字符。

从代码的角度:系统调用主要使用函数open打开一个文件,然后再返回一个文件描述符,而write、read等系统调用函数再对这个文件描述符进行操作,库函数调用主要使用函数fopen打开一个文件,然后再返回一个指向文件的指针,而fwrite、fread等库函数再对这个指针进行操作。

它们的代码的实现是非常类似的。


关于对文件的总结,我发现这位仁兄已经总结过,非常不错。(内容基本都来自Linux程序设计)

http://www.cnblogs.com/yanlingyin/archive/2012/08/04/2617209.html

那我展现几个常见的例子吧。

2、系统调用例子

2.1、对文件进行写操作

功能:程序向打开的文件写入字符串“hello world”

/*
 * test.c
 *
 *  Created on: 2016年7月17日
 *      Author: Andy_Cong
 */
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<errno.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
int main(int argc,char *argv[])
{
	if(argc<2)
		return 0;
	//用读写追加方式打开一个已经存在的文件
	int fd=open(argv[1],O_RDWR|O_APPEND);
	if(fd==-1)
	{
		printf("error is %s\n",strerror(errno));
	}
	else
	{
		//打印文件描述符号
		printf("success fd = %d\n",fd);
		char buf[100];
		memset(buf,0,sizeof(buf));
		strcpy(buf,"hello world\n");
		write(fd,buf,strlen(buf));
		close(fd);
	}
	return 0;
}
运行结果:

...
stu@ubuntu:~/Test/write$ ls
abc.txt  makefile  test.c
stu@ubuntu:~/Test/write$ cat abc.txt
stu@ubuntu:~/Test/write$ make
gcc -Wall -g -o test.o -c test.c
gcc -o test test.o
----------------ok------------
stu@ubuntu:~/Test/write$ cat abc.txt
stu@ubuntu:~/Test/write$ ./test abc.txt
success fd = 3
stu@ubuntu:~/Test/write$ cat abc.txt
hello world
stu@ubuntu:~/Test/write$ 
....
向屏幕文件写数据。(屏幕也是一个文件设备)

...
stu@ubuntu:~/Test/write$ tty
/dev/pts/1
stu@ubuntu:~/Test/write$ ./test /dev/pts/1
success fd = 3
hello world
stu@ubuntu:~/Test/write$ 
...


2.2、读文件。

功能:向文件读取内容(文件内容为上面例子写入的内容)


/*
 * test3.c
 *
 *  Created on: 2016年7月17日
 *      Author: Andy_Cong
 */
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<errno.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
int main(int argc,char *argv[])
{
    if(argc<2)
	   return 0;
    int fd = open(argv[1],O_RDONLY);
    if(fd==-1)
    {
    	printf("error is %s\n",strerror(errno));
    }
    else
    {
    	printf("success fd = %d\n",fd);
        char buf[100];
        memset(buf,0,sizeof(buf));
        while(read(fd,buf,sizeof(buf))>0)
        {
        	printf("%s\n", buf);
        	memset(buf, 0, sizeof(buf));
        }
        close(fd);
    }
    return 0;
}

运行结果:
..
stu@ubuntu:~/Test/read$ ls
abc.txt  makefile  test.c
stu@ubuntu:~/Test/read$ cat abc.txt
hello world
stu@ubuntu:~/Test/read$ make
gcc -Wall -g -o test.o -c test.c
gcc -o test test.o
----------------ok------------
stu@ubuntu:~/Test/read$ ./test abc.txt
success fd = 3
hello world

stu@ubuntu:~/Test/read$ 
...


3、库函数调用

3.1、写文件

功能:库函数调用,向打开文件文件写数据(也可以写入二进制)

/*
 * 
 * */

#include<stdio.h>
#include<stdlib.h>
#include<errno.h>
#include<string.h>
struct person
{
	int id;
	char name[20];
	int age;
	int sex;
	char tel[20];
};
int main(int arg, char *args[])
{
	FILE *p = fopen(args[1], "w");
	if (p == NULL)
	{
		printf("error is %s\n", strerror(errno));
	} else
	{
		printf("success\n");
		struct person man[10];
		memset(&man, 0, sizeof(man));

		man[0].id = 0;
		strcpy(man[0].name, "刘德华");
		man[0].age = 18;
		man[0].sex = 1;
		strcpy(man[0].tel, "110");
		man[1].id = 1;
		strcpy(man[1].name, "张学友");
		man[1].age = 20;
		man[1].sex = 0;
		strcpy(man[1].tel, "119");

		fwrite(&man, sizeof(struct person), 2, p);
		fclose(p);
	}
	return 0;
}


3.2、读文件

功能:库函数,向打开文件文件读取数据(也可以读取二进制)

/*
*/
struct person
{
	int id;
	char name[20];
	int age;
	int sex;
	char tel[20];
};


int main(int arg, char *args[])
{
	FILE *p = fopen(args[1], "w");
	if (p == NULL)
	{
		printf("error is %s\n", strerror(errno));
	} else
	{
		printf("success\n");
		struct person man;
		memset(&man, 0, sizeof(man));

		while(fread(&man, sizeof(struct person), 1, p))
		{
			printf("id=%d\n", man.id);
			printf("name=%s\n", man.name);
			printf("age=%d\n", man.age);
			printf("tel=%s\n", man.tel);
		}
		fclose(p);
	}
	return 0;
}

4 另外两个实例(关于文件属性和wirite log)

4.1、判断文件属性例子

/*
 * test.c
 *
 *  Created on: 2016年7月20日
 *      Author: Andy_Cong
 */

//文件结构例子  判断文件类型

//All of these system calls return a stat structure, which contains the
//following fields:
//
//文件结构
//struct stat {
//	dev_t st_dev; /* ID of device containing file */
//	ino_t st_ino; /* inode number */
//	mode_t st_mode; /* protection */
//	nlink_t st_nlink; /* number of hard links */
//	uid_t st_uid; /* user ID of owner */
//	gid_t st_gid; /* group ID of owner */
//	dev_t st_rdev; /* device ID (if special file) */
//	off_t st_size; /* total size, in bytes */
//	blksize_t st_blksize; /* blocksize for file system I/O */
//	blkcnt_t st_blocks; /* number of 512B blocks allocated */
//	time_t st_atime; /* time of last access */
//	time_t st_mtime; /* time of last modification */
//	time_t st_ctime; /* time of last status change */
//};

//
//int fstat(int fd, struct stat *buf);
//is identical to stat(), except that the file to be stat-ed
//is specified by the file descriptor fd.

//检查文件类型
//The following POSIX macros are defined to check the file type
//using thest_mode field:
//S_ISREG(m) is it a regular file?
//S_ISDIR(m) directory?
//S_ISCHR(m) character device?
//S_ISBLK(m) block device?
//S_ISFIFO(m) FIFO (named pipe)?
//S_ISLNK(m) symbolic link? (Not in POSIX.1-1996.)
//S_ISSOCK(m) socket? (Not in POSIX.1-1996.)
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
int main(int argc, char *argv[])
{
	if (argc < 2)
		return 0;
	int fd = open(argv[1], O_RDONLY);
	if (fd == -1)
	{
		printf("error is :%s", strerror(errno));
	}
	else
	{
		printf("open success fd= %d\n", fd);
		struct stat buf;
		fstat(fd, &buf);
		if (S_ISREG(buf.st_mode))
		{
			printf("%s is charfile\n", argv[1]);
		}
		if (S_ISDIR(buf.st_mode))
		{
			printf("%s is direction\n", argv[1]);
		}
		//.....
		printf("%s size=%d\n", argv[1], buf.st_size);
		close(fd);
	}
	return 0;
}


//运行结果
//stu@ubuntu:~/Test/stat$ ./test makefile
//open success fd= 3
//makefile is charfile
//makefile size 219
//stu@ubuntu:~/Test/stat$ ls -l
//total 24
//-rw------- 1 stu stu  219 Jul 20 03:48 makefile
//-rwxrwxr-x 1 stu stu 9255 Jul 20 03:48 test
//-rw------- 1 stu stu 1996 Jul 20 03:48 test.c
//-rw-rw-r-- 1 stu stu 4088 Jul 20 03:48 test.o


4.2、写log

/*
 * test.c
 *
 *  Created on: 2016年7月20日
 *      Author: Andy_Cong
 */
#include<stdio.h>
#include<stdlib.h>
#include <time.h>
#include<errno.h>
//tm结构
//struct tm
//{
//	int tm_sec; /* seconds */
//	int tm_min; /* minutes */
//	int tm_hour; /* hours */
//	int tm_mday; /* day of the month */
//	int tm_mon; /* month */
//	int tm_year; /* year */
//	int tm_wday; /* day of the week */
//	int tm_yday; /* day in the year */
//	int tm_isdst; /* daylight saving time */
//};

void writelog(const char *fileName,const char *log)
{
	time_t tDate;
	struct tm *eventTime;
	time(&tDate); //得到系统时间
	eventTime = localtime(&tDate);//将time_t数据类型转化为struct tm 结构
	int iYear=eventTime->tm_year;
	int iMon = eventTime->tm_mon + 1;
    int iDay = eventTime->tm_mday;
	int iHour = eventTime->tm_hour;
	int iMin = eventTime->tm_min;
	int iSec = eventTime->tm_sec;
	printf("tm_isdst = %d\n", eventTime->tm_isdst);
	char sDate[16];
	sprintf(sDate, "%04d-%02d-%02d", iYear, iMon, iDay);
	char sTime[16];
	sprintf(sTime, "%02d:%02d:%02d", iHour, iMin, iSec);
	char s[1024];
	sprintf(s, "%s %s %s\n", sDate, sTime, log);
	FILE *p = fopen(fileName, "a+");
	if (p == NULL)
	{
		printf("write log %s error: %s\n",fileName,strerror(errno));
	}
	else
	{
		fputs(s, p);
		fclose(p);
	}
	return;
}
int main(int argc,char *argv[])
{
	if(argc<2)
		return 0;
	writelog(argv[1],"write log");
	return 0;
}
//运行结果
//stu@ubuntu:~/Test/log$ ls
//makefile  test  test.c  test.o
//stu@ubuntu:~/Test/log$ ./test abc.txt hello
//tm_isdst = 1
//stu@ubuntu:~/Test/log$ cat abc.txt
//0116-07-20 04:22:38 write log
//stu@ubuntu:~/Test/log$



Linux-(C)文件读写实例(系统调用/标准I/O库)

标签:

原文地址:http://blog.csdn.net/qq_33850438/article/details/51969805

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!