📄 文件和设备编程.htm
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD><TITLE>文件和设备编程</TITLE>
<META http-equiv=Content-Type content="text/html; charset=gb2312">
<META content="MSHTML 6.00.2800.1400" name=GENERATOR></HEAD>
<BODY style="FONT-SIZE: 9pt; FONT-FAMILY: 宋体">
<CENTER>
<TABLE cellSpacing=10 cellPadding=10 width="60%" bgColor=#ffb693>
<TBODY>
<TR>
<TD align=middle><FONT
size=+2><!--标题由此开始-->文件和设备编程</FONT></TD></TR></TBODY></TABLE></CENTER>
<P>
<H3>目 录</H3><!--目录由此开始--><A id=Content name=Content></A>
<OL>
<LI><A
href="file:///E:/linux资料/linux笔记及源码/joyfire-0206.htm/system/10.html#I318">文件和设备编程</A>
<OL>
<LI><A
href="file:///E:/linux资料/linux笔记及源码/joyfire-0206.htm/system/10.html#I319">文件访问原语</A>
<LI><A
href="file:///E:/linux资料/linux笔记及源码/joyfire-0206.htm/system/10.html#I320">网卡驱动编写</A>
<OL>
<LI><A
href="file:///E:/linux资料/linux笔记及源码/joyfire-0206.htm/system/10.html#I321">概述</A>
<LI><A
href="file:///E:/linux资料/linux笔记及源码/joyfire-0206.htm/system/10.html#I322">设备驱动</A>
<LI><A
href="file:///E:/linux资料/linux笔记及源码/joyfire-0206.htm/system/10.html#I323">需要注意</A>
<LI><A
href="file:///E:/linux资料/linux笔记及源码/joyfire-0206.htm/system/10.html#I324">参考</A>
</LI></OL>
<LI><A
href="file:///E:/linux资料/linux笔记及源码/joyfire-0206.htm/system/10.html#I325">设备驱动</A>
<OL>
<LI><A
href="file:///E:/linux资料/linux笔记及源码/joyfire-0206.htm/system/10.html#I326">概述</A>
<LI><A
href="file:///E:/linux资料/linux笔记及源码/joyfire-0206.htm/system/10.html#I327">数据结构</A>
<LI><A
href="file:///E:/linux资料/linux笔记及源码/joyfire-0206.htm/system/10.html#I328">初始化</A>
<LI><A
href="file:///E:/linux资料/linux笔记及源码/joyfire-0206.htm/system/10.html#I329">管理流程</A>
<LI><A
href="file:///E:/linux资料/linux笔记及源码/joyfire-0206.htm/system/10.html#I330">添加字符设备</A>
<LI><A
href="file:///E:/linux资料/linux笔记及源码/joyfire-0206.htm/system/10.html#I331">添加块设备</A>
<LI><A
href="file:///E:/linux资料/linux笔记及源码/joyfire-0206.htm/system/10.html#I332">一个虚拟的字符设备驱动程序</A>
<LI><A
href="file:///E:/linux资料/linux笔记及源码/joyfire-0206.htm/system/10.html#I333">代码范例</A>
<OL>
<LI><A
href="file:///E:/linux资料/linux笔记及源码/joyfire-0206.htm/system/10.html#I334">header.c</A>
<LI><A
href="file:///E:/linux资料/linux笔记及源码/joyfire-0206.htm/system/10.html#I335">init.c</A>
<LI><A
href="file:///E:/linux资料/linux笔记及源码/joyfire-0206.htm/system/10.html#I336">ioctl.c</A>
<LI><A
href="file:///E:/linux资料/linux笔记及源码/joyfire-0206.htm/system/10.html#I337">open.c</A>
<LI><A
href="file:///E:/linux资料/linux笔记及源码/joyfire-0206.htm/system/10.html#I338">read.c</A>
<LI><A
href="file:///E:/linux资料/linux笔记及源码/joyfire-0206.htm/system/10.html#I339">release.c</A>
<LI><A
href="file:///E:/linux资料/linux笔记及源码/joyfire-0206.htm/system/10.html#I340">tdd.c</A>
<LI><A
href="file:///E:/linux资料/linux笔记及源码/joyfire-0206.htm/system/10.html#I341">write.c</A>
</LI></OL></LI></OL>
<LI><A
href="file:///E:/linux资料/linux笔记及源码/joyfire-0206.htm/system/10.html#I316">读写音频</A>
<OL>
<LI><A
href="file:///E:/linux资料/linux笔记及源码/joyfire-0206.htm/system/10.html#I732">录音</A>
<LI><A
href="file:///E:/linux资料/linux笔记及源码/joyfire-0206.htm/system/10.html#I733">调节音量</A>
</LI></OL>
<LI><A
href="file:///E:/linux资料/linux笔记及源码/joyfire-0206.htm/system/10.html#I342">pro结构</A></LI></OL></LI></OL>
<HR>
<BR><A id=I318 name=I318></A>
<CENTER><B><FONT size=+2>文件和设备编程</FONT></B></CENTER><BR>
<CENTER><A
href="file:///E:/linux资料/linux笔记及源码/joyfire-0206.htm/system/10.html#Content">[目录]</A></CENTER>
<HR>
<BR><A id=I319 name=I319></A>
<CENTER><B><FONT size=+2>文件访问原语</FONT></B></CENTER><BR> POSIX
API 最重要的一个抽象概念就是文件。尽管几乎所有的操作系统都将文件用于永久性存储器,但所有 Unix 版本通过文件抽象概念提供对大多数系统资源的访问。
<P> 更具体地说,这意味着 Linux 使用相同的一组系统调用来提供对设备(例如软盘和磁带设备)、网络资源(最常见的是
TCP/IP 连接)、系统终端,甚至内核状态信息的访问。感谢无所不在的系统调用,娴熟地使用与文件相关的调用对于每个 Linux
程序员来说都很重要。让我们仔细查看一下文件 API 背后的一些基本概念,并描述最重要的文件相关系统调用。
<P> Linux
提供许多不同种类的文件。最常见的类型就简称为常规文件,它存储大量用于以后访问的信息。您所使用的绝大部分文件 -- 例如可执行文件(如
/bin/vi)、数据文件(如 /etc/passwd)和系统二进制文件(如 /lib/libc.so.6)--
都是常规文件。它们通常驻留在磁盘上的某处,但我们稍后会发现,并不一定都是这种情况。
<P> 另一种文件类型是目录,它包含了一个其它文件及其位置的列表。使用 ls
命令列出目录中的文件时,它打开该目录的文件,并打印出它所包含的所有文件的信息。
<P>
其它文件类型包括块设备(表示文件系统高速缓存的设备,例如硬盘驱动器)、字符设备(表示非高速缓存的设备,例如磁带驱动器、鼠标和系统终端)、管道和套接字(允许进程相互之间对话),以及符号链接(允许文件在目录层次结构中有多个名称)。
<P> 大多数文件都有一个或多个引用它们的符号名。这些符号名是一组由 / 字符定界的字符串,并向内核标识文件。它们是
Linux 用户所熟悉的路径名;例如,路径名 /home/ewt/article
引用的是我手提电脑中包含这篇文章文本的文件。没有两个文件可以共享相同的名称(但单一文件可以有多个名称),因此路径名唯一地标识单一文件。
<P>
进程可以访问的每个文件都由一个小的非负整数标识,称为“文件描述符”。文件描述符由打开文件的系统调用创建,并由从当前进程创建的新子进程继承。就是说,当进程启动了一个新程序时,原始进程的打开文件通常是由新程序继承的。
<P> 按照约定,大多数程序保留前三个文件描述符(0、1 和 2)用于特殊目的 --
访问所谓的标准输出、标准输出和标准错误流。文件描述符 0 是标准输入,这里许多程序都将从外部世界接收输入。文件描述符 1
是标准输出。大多数程序在这里显示正常的输出。对于与错误情况相关的输出,使用文件描述符 2(标准错误)。
<P> 任何习惯使用 Linux shell 的人都曾看到过标准输入、输出和错误文件描述符的使用。通常,shell
运行命令时带文件描述符 0、1 和 2,都是指 shell 的终端。当使用 > 字符指示 shell 将一个程序的输出发送给另一个程序时,shell
在调用新程序之前打开该文件作为文件描述符 1。这将导致程序将它的输出发送给指定的文件而不是用户终端;其妙处是,对于程序本身,这是透明的!
<P> 与之类似,"<" 字符指示 shell 使用特定的文件作为文件描述符
0。这样就强迫程序从该文件中读取它的输入;这两种情况下,任何来自程序的错误仍将出现在终端上,如同它们在文件描述符 2 的情况下发送给标准错误一样。(在
"bash" shell 中,可以使用 2> 而不是 > 将标准错误重定向)。这种类型的文件重定向是 Linux 命令行最强大的特性之一。
<P> 使用任何与文件相关的系统调用之前,程序应该包括 <fcntl.h> 和
<unistd.h>;它们为最普遍的文件例程提供了函数原型和常数。在下面的示例代码中,我们假设每个程序开始处都有
<P>#include <fcntl.h><BR>#include <unistd.h>
<P> 首先,让我们了解如何读写文件。凭直觉就可以知道,read() 和 write()
系统调用是执行这些操作的最常用方法。这两种系统调用将有三个自变量:要访问的文件描述符、指向要读写的信息的指针以及应该读写的字符数。返回成功读写的字符数。清单 1
说明了一个简单的程序,它从标准输入(文件描述符 0)中读取一行,并将它写入标准输出(文件描述符 1):
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -