zoukankan      html  css  js  c++  java
  • linux之操作磁盘文件与tty设备文件

       stty用于改变和显示终端的设置信息,准确的说是改变终端驱动程序的设置信息.tty的驱动程序位于内核,内核用于连接外部世界(磁盘文件、设备文件)与进程间的数据交换.而tty也属于设备文件中的一种,

       现在介绍两种操作磁盘文件的方式,分别采用系统的函数调用和C语言的库函数调用.

         第一种:系统库函数

      

    #include <stdio.h>
    #include <fcntl.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    
    #define LENGTH 100
    
    int main()
    {
    
    	int fd,len;
    	char str[LENGTH];
    	char *content="undergrowth";
    	fd=open("un.txt",O_CREAT | O_RDWR,S_IRUSR|S_IWUSR);
     	if(fd)
    	{
    		write(fd,content,strlen(content));
    		close(fd);
    	}else
    	{
    		exit(0);
    	}
    	fd=open("un.txt",O_RDONLY);
    	len=read(fd,str,LENGTH);
    	printf("%s
    ",str);
    	close(fd);
    	return 0;
    }
    
     使用 gcc -Wall hello.c -o un 编译即可 运行 ./un

      上面使用open以所有者可读可写的权限来操作un.txt文件  使用write写完数据后 关闭文件描述符


    第二种方式:C语言的库函数

      

    #include <stdio.h>
    
    #define  LENGTH 100
    
    
    int main()
    {
    	FILE *fd;
    	char str[LENGTH];
    	char *content="undergrowth";
    	fd=fopen("un.txt","w+");
    	if(fd)
    	{
    		fputs(content,fd);
    		fclose(fd);
    	}
    
    	fd=fopen("un.txt","r");
    	fgets(str,LENGTH,fd);
    	printf("%s
    ",str);
    	fclose(fd);
    	return 0;
    }
    

       使用 gcc -Wall hello.c -o un 编译即可 运行 ./un

    上面使用fopen以读写的方式打开un.txt,如果不存在,则进行创建,然后使用fputs向磁盘文件中写入数据,之后在使用fgets从磁盘文件中获取LENGTH长度的字符放入str字符数组中


      接下来介绍tty设备文件

       磁盘文件与设备文件有很多相似的地方,比如都有文件的属性、文件的大小、文件的修改时间、文件的节点等等之类的,都可用系统的库函数与C语言的库函数来进行open、read、write、close、ioctl来进行操作。

      那么内核如何区分文件时磁盘文件还是设备文件呢?

        这里就要看磁盘文件和设备文件共有的一个属性即文件节点,当内核要准备为文件读数据时,首先会看文件的文件节点属性,如果文件节点对应的是磁盘文件的话,则直接根据文件系统的映射表读取数据,如果是设备文件的话,则会调用设备文件的驱动程序的read方法进行读取.

      磁盘文件在进行读写的时候是有缓冲区的,而设备文件是没有缓冲区的.

      而对于tty设备文件,我们可以通过tcgetattr、tcsetattr来对其驱动程序的属性进行读取和重新设置,从而影响其正常的工作.

    下面是一个显示tty驱动设备的属性的小程序,只显示了几个比较重要的属性,更多的可以使用man tcgetattr来进行查看

    #include <stdio.h>
    #include <termios.h>
    #include <stdlib.h>
    
    
    #define eops(s,x) {perror(s); exit(x);}
    
    int main()
    {
    	struct termios ttyinfo;
    	void showbaud(int);
    	void show_someflag(struct termios *);
    	if((tcgetattr(0,&ttyinfo))==-1) eops("tcgetattr",1); //获取到当前终端的设置信息保存在ttyinfo结构体中
    	showbaud(cfgetospeed(&ttyinfo)); //显示输出波特率
    	printf("the erase charcter is ascii %d,Ctrl-%c
    ",ttyinfo.c_cc[VERASE],ttyinfo.c_cc[VERASE]);
    	show_someflag(&ttyinfo); //显示当前终端的一些设置信息
    	return 0;
    }
    
    
    void showbaud(int speed)
    {
    	printf("the baud rate is %d .
    ",speed);
    }
    
    struct flaginfo { //用于保存属性名及其描述
    	int fl_value;
    	char *fl_desc;
    };
    
    struct flaginfo input_flag[]={  //构建输入属性
    	{IGNBRK,"ignore break condition"},
    	{INLCR,"map nl to cr on input"},
    	{IXOFF,"enable start/stop input control"},
    	{0,NULL}
    };
    
    
    struct flaginfo output_flag[]={ //构建输出属性
    	{OLCUC,"map lowercase character to uppercase character on output"},
    	{0,NULL}
    };
    
    struct flaginfo local_flag[]={//构建本地属性
    	{ECHO,"echo input character"},
    	{ISIG,"when any on character intr,quit,susp or dsusp are received,generate the corresponing the signal"},	
    	{0,NULL}
    };
    
    struct flaginfo control_flag[]={//构建控制属性
    	{CREAD,"enalbe receiver"},
    	{CRTSCTS,"enable rts/cts flow control"},
    	{0,NULL}
    };
    
    
    
    void show_flagset(int thevalue,struct flaginfo fi[]) 
    {
    	int i;
    	for(i=0;fi[i].fl_value;i++)
    		{
    			printf(" %s is ",fi[i].fl_desc);
    			if(fi[i].fl_value&thevalue) printf("on.
    ");  //判断该属性是否已经打开
    			else printf("off.
    ");
    		}
    }
    
    void show_someflag(struct termios *termios_p) 
    {
    	printf("display some flag as follow:
    ");
    	show_flagset(termios_p->c_iflag,input_flag);
    	show_flagset(termios_p->c_oflag,output_flag);
    	show_flagset(termios_p->c_lflag,local_flag);
    	show_flagset(termios_p->c_cflag,control_flag);
    }
    


      还有一个是两个终端进行相互通信

    #include <stdio.h>
    #include <fcntl.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <string.h>
    
    
    //#define BUFSIZ 30
    
    int main(int argc,char *argv[])
    {
    	int fd;
    	char buf[BUFSIZ];
    	if(argc!=2)
    	{
    		perror("usage:write ttyname.
    ");
    		exit(1);
    	}
    	fd=open(argv[1],O_WRONLY); //获取另外一个终端的名字
    	if(fd==-1)
    		{
    		 perror(argv[1]);
    		exit(1);
    		}
    	while(fgets(buf,BUFSIZ,stdin)!=NULL)//从当前终端获取信息
    	{
    	if(write(fd,buf,strlen(buf))==-1) break; //将信息写入到另外一个终端
    	}
    	close(fd);
    	return 0;
    }
    


  • 相关阅读:
    用node.js解决编程题的输入问题
    css兼容篇
    关于Hogan的学习笔记
    javascript实现瀑布流
    代码管理工具之SVN简介
    原创•模板匹配实践之Opencv+Python识别PDB板图片
    sklearn 神经网络MLPclassifier参数详解
    (转)knn算法简单实例分享
    机器学习初识——KNN算法
    开发工具VScode实用插件推荐分享
  • 原文地址:https://www.cnblogs.com/liangxinzhi/p/4275605.html
Copyright © 2011-2022 走看看