Input and Output I/O操作函数

来源:互联网 发布:淘宝订单自己消失 编辑:程序博客网 时间:2024/06/06 00:47

Linux部分转自http://blog.csdn.net/songguozhi/article/details/3085841,未验证

Windows部分转自MSDN



Linux

Low-level I/O 和 File System Interface

 1. 为什么需要使用 low-level I/O,glibc 里面提到了一些情形,对大量二进制数
据进行操作,某些文件上的操作只能通过 descriptor(设置一些权限,如锁),
把一些资源传递给子进程。使用 low-level I/O 的很多函数是把前面 stream 的
那个 f 去掉了,如
int open (const char *filename,int flags[, mode_t mode])
int creat (const char *filename, mode_t mode)
int close (int filedes)
ssize_t read (int filedes, void *buffer, size_t size)
ssize_t pread (int filedes, void *buffer, size_t size, off_t offset)
ssize_t write (int filedes, const void *buffer, size_t size)
ssize_t pwrite (int filedes, const void *buffer, size_t size, off_t offset)
off_t lseek (int filedes, off_t offset, int whence)
一些不同在于,这些函数对 file descriptor 操作(就是一个 int)。文件打开的权限
可以为 O_RDONLY,O_WRONLY,O_RDWR,但是 POSIX.1 下面最好用 O_READ,
O_WRITE,O_EXEC,这是所谓的 access modes,另外还有 Open-time flags,如
O_CREAT(不存在就创建),O_EXCL(和前者同时使用表示存在即报错),
O_NONBLOCK(打开某些设备如串口时避免等待很长时间,之后如果 I/O 需要 block 可
利用 fcntl 更改),O_NOCTTY(针对终端设备,不懂 @@),O_IGNORE_CTTY(同),
O_NOLINK(打开的文件是符号连接本身),O_NOTRANS(不进行 translate 工作),
O_TRUNC(截断原来的东西,ms w 就是干这个事情了),O_SHLOCK(共享锁,允许
其他的进程读),O_EXLOCK(排除性锁,不允许其他的读写),另外有一些 I/O
operating modes,如 O_APPEND(指向文件尾),O_ASYNC(允许异步读写,通
过 SIGIO 信号),O_FSYNC(同步写入文件),O_NOATIME(不更新 access time)。
其中 p 类型的读写表示根据到文件头的偏移进行的,另外 create 函数是 obsolete 的。
这里没有类似的 tell 函数,但是可以用 lseek (desc, 0, SEEK_CUR) 获得。
可以使用
FILE * fdopen (int filedes, const char *opentype)
建立一个 stream 关联到该 descriptor 上,而
int fileno (FILE *stream)
int fileno_unlocked (FILE *stream)
将返回某个 stream 的 descriptor,通常 stdin、stdout 和 stderr 的 descriptor 可以用
STDIN_FILENO、STDOUT_FILENO、STDERR_FILENO 表达。可见同一个 descriptor
上可以建立不同的 stream,这时两个 streams 其实是 linked 在一起,即具有相同的当前
文件指针(不是说 FILE*,这其实是 stream 的地址)等等。另外可以用
int dup (int old)
int dup2 (int old,int new)
产生 linked 在一起的 descriptor(编号不同),后者使用 new 原来的编号但使用的 old 的
信息;前者返回的最小的未使用的 descriptor 作为 old 的“复制品”。后面讲述 fcntl() 会进一
步解释这两个函数的。清理一个 stream 可以使用
int fclean (FILE *stream)
其作用基本和 fflush() 近似。

2. 快速 scatter-gather I/O,解决的问题是把从一个地方读出的数据快速传输到几个不同的
buffer 中,数据是一个一个 buffer 填满,然后下一个,直到输入结束或填满了所有的 buffer,
描述一个 buffer 使用一个 struct iovec,其成员 void *iov_base 描述缓存区地址,size_t iov_len
是缓存区大小,使用(sys/uio.h)
ssize_t readv (int filedes, const struct iovec *vector, int count)
从 descriptor 读入到 iovec 指向的结构体所描述的缓存中,该区域一共包含 count 个缓存区。
写入使用
ssize_t writev (int filedes, const struct iovec *vector, int count)

3. 现代操作系统多支持所谓 mmap(memory mapped)的方式快速读写文件,往往一个
page 存储一段数据,页面大小可以用
size_t page_size = (size_t) sysconf (_SC_PAGESIZE);
获得,然后将文件内容映射到一个内存区域(sys/mman.h)
void * mmap (void *address, size_t length,int protect, int flags,int filedes, off_t offset)
void * mremap (void *address, size_t length, size_t new_length,int flag)
读写内存后就可以把改动存储到文件中,读写完后需要
int munmap (void *addr, size_t length)
如果需要显示将读写同步,应调用
int msync (void *address, size_t length,int flags)
下面我们解释一下相关的参数,mmap 将 fildes 对应 offset 开始 长度为 length 的数据
映射到 address 处(希望在这里 @@),可以为 NULL,然后会分配的,protect 是
权限,有 PROT_READ、PROT_WRITE、PROT_EXEC。而 flags 表明使用的一些
其他的 MAP_PRIVATE(不写回文件),MAP_SHARED(写回文件,这样其他打开
该文件的程序会立即看见),MAP_FIXED(使用 address 否则 fail),MAP_ANON
(仅仅创建一个内存块,不与文件关联)。使用 munmap 时只会释放正好一个或多个
pages,不会释放一部分(尽管可以这么调用)。在 msync 里面的 flags 可以为 MS_SYNC
(保证写到磁盘上),MS_ASYNC(可以开始同步,但理解返回,不会 block)。
另外为了更高效的利用这种内存,可以提出一些建议
int madvise (void *addr, size_t length,int advice)
其中,advice 可以是 MADV_NORMAL(正常处理),MADV_RANDOM(会被随机访问),
MADV_SEQUENTIAL(会被顺序访问),MADV_WILLNEED(不懂),MADV_DONTNEED(ft...)。
这部分看点 paging 再看比较合适 -.-

4. 需要检查多个输入输出是否有数据到达可以使用
int select (int nfds, fd_set *read-fds, fd_set *write-fds, fd_set *except-fds, struct timeval *timeout)
其中使用 nfds 表示有多少个 descriptor 被监视,他们放在 read-fds、write-fds 和 except-fds 中,
并用 timeout 所指向表示一个超时(过后不待 @@),宏 FD_SETSIZE 决定一个 descriptor 的集合
的大小,我们需要 fd_set 存放 descriptors,可以用以下宏操纵:
void FD_ZERO (fd_set *set)
void FD_SET (int filedes, fd_set *set)
void FD_CLR (int filedes, fd_set *set)
int FD_ISSET (int filedes, const fd_set *set)
依次表示一个空的 fd_set、添加一个 descriptor、清除一个 descriptor、测试是否属于该 fd_set。
如果超时,select 返回 0,如果出现错误、接收到 signal 则返回。

5. 同步 I/O 常用下面的函数
int sync (void)
int fsync (int fildes)
int fdatasync (int fildes)

6. 异步输入输出,不同在于函数会立即返回,操作排在队列中回自动进行,其控制过程用
struct aiocb 决定,其包含控制某个读写的信息,如 descriptor、偏移等等。下面的操作
进行读写等等
int aio_read (struct aiocb *aiocbp)
int aio_write (struct aiocb *aiocbp)
int lio_listio (int mode,struct aiocb *const list[],int nent, struct sigevent *sig)
int aio_error (const struct aiocb *aiocbp)
ssize_t aio_return (const struct aiocb *aiocbp)
int aio_fsync (int op,struct aiocb *aiocbp)
int aio_suspend (const struct aiocb *const list[],int nent, const struct timespec *timeout)
int aio_cancel (int fildes,struct aiocb *aiocbp)
这些函数分别实现了读、写、批量读写、侦测错误、查看返回值、同步数据、暂停、取消
这些功能。同时还可以用 struct aioinit 结构进行优化,这需要首先用
void aio_init (const struct aioinit *init)
然后用户设定的策略就可以被应用到后面的 AIO 上了。

6. fcntl 的功能
int fcntl (int filedes,int command, ...)
有很多,如 F_DUPFD 复制 discriptor、F_GETFD(获得 descriptor 的 flags)、F_GETFL
(获得打开文件的 flags)、F_GETLK(获得文件的 lock)、F_GETOWN(获取进程 gid),
对应的 GET 都有 SET 版本,多了一个 F_SETLKW 表示等待完成才返回。比如前面的 dup
可以 fcntl (old, F_DUPFD, 0) 实现。文件 descriptor flags 中有 FD_CLOEXEC 表示在
exec 之后是否关闭。

7. 一些其他的控制使用
int ioctl (int filedes,int command, ...)
完成,如控制终端的行为等。

8. 关于目录的几个函数
char * getcwd (char *buffer, size_t size)
char * getwd (char *buffer)
char * get_current_dir_name (void)
这三个都是获得目录,中间一个最好不用,其实使 buffer 为 NULL 等价第三个,都是
malloc 出来需要 free 的。下面的是用于改变当前目录:
int chdir (const char *filename)
int fchdir (int filedes)
注意这里面很多 f 开头的却不是 stream 都是用的 descriptor。
为了处理一般的目录里面的东西,需要一个结构 dirent 描述,里面包含了诸如 d_name
名称,d_fileno(inode),d_type(类型)这些东西。其中 d_type 是 mode_t 类型,
可以用
int IFTODT (mode_t mode)
mode_t DTTOIF (int dtype)
互相转化(宏)。首先必须打开一个目录,这使用的是
DIR * opendir (const char *dirname)
它创建了一个 stream,而
int dirfd (DIR *dirstream)
将返回它的 descriptor,然后用
struct dirent * readdir (DIR *dirstream)
int readdir_r (DIR *dirstream, struct dirent *entry, struct dirent **result)
读入需要的东西(directory entry),后者是 thread-safe 的。读完后用
int closedir (DIR *dirstream)
关闭这个流。如果需要以某种特定的方式,如依照字母序来访问一个 directory 里面的
东西,就可以使用
int scandir (const char *dir,struct dirent ***namelist, int (*selector) (const struct dirent *),int (*cmp) (const void *,const void *))
其中可以用来作为 cmp 的为
int alphasort (const void *a,const void *b)
int versionsort (const void *a,const void *b)
这类函数,一般使用 scandir 扫描一个目录,用 select 筛选,cmp 排序,由于 dirent
是用 malloc 分配的事后需要释放。
另外有
int ftw (const char *filename, __ftw_func_t func,int descriptors)
int nftw (const char *filename, __nftw_func_t func,int descriptors, int flag)
其中
typedef int (*__ftw_func_t) (const char *,const struct stat *, int)
typedef int (*__nftw_func_t) (const char *,const struct stat *, int, struct FTW *)
其用途在于 ftw()(file tree walk)将从 filename 开始遍历整棵树,将 func 作用在每一个节点上,
其中 stat 是其 file stat,另一个 int 是文件类型。descriptors 限制最多使用的 descriptors 数目。
而 nftw 稍微不同一点在于后面的 flag 可以 OR 到所有的 func 调用的 int 上去。

9. 关于链接,可以用下面的函数
int link (const char *oldname,const char *newname)
int symlink (const char *oldname,const char *newname)
前者用于建立硬链接,后者是符号链接,可以用
int readlink (const char *filename,char *buffer, size_t size)
读出符号链接的目标文件。函数
char * canonicalize_file_name (const char *name)
返回不含有 . 或者 .. 的典则文件名。而
char * realpath (const char *restrict name,char *restrict resolved)
类似,只是放到 resolved 里面(除非为 NULL 就和前者一样了)。
删除文件就是一个 link 的反过程
int unlink (const char *filename)
而这是删除目录,
int rmdir (const char *filename)
ISO C 里面定义了
int remove (const char *filename)
它对文件目录都 work。
int rename (const char *oldname,const char *newname)
重命名文件,
int mkdir (const char *filename, mode_t mode)
创建目录, mode_t 声明了权限,

10. 文件权限常用 struct stat 表示,里面含有多数我们关心的信息,如 st_mode(类型、权限),
st_ino(inode),st_nlink(硬连接数),属主,大小,访问、修改、修改属性时间等。一般使用
int stat (const char *filename,struct stat *buf)
int fstat (int filedes,struct stat *buf)
int lstat (const char *filename,struct stat *buf)
这其中某个函数获得,最后一个是不会 follow 符号链接的。有一系列的 macro 能够检测我们需要的
类型等,如
int S_ISDIR (mode_t m)
int S_ISCHR (mode_t m)
int S_ISBLK (mode_t m)
int S_ISREG (mode_t m)
int S_ISFIFO (mode_t m)
int S_ISLNK (mode_t m)
int S_ISSOCK (mode_t m)
int S_TYPEISMQ (struct stat *s)
int S_TYPEISSEM (struct stat *s)
int S_TYPEISSHM (struct stat *s)
我们可以用以下函数更改文件属主,
int chown (const char *filename, uid_t owner, gid_t group)
可以用下面函数设置 umask
mode_t umask (mode_t mask)
调用该函数设置了 umask 同时会返回原来的 umask。可以直接用
mode_t getumask (void)
获得 umask,
int chmod (const char *filename, mode_t mode)
int fchmod (int filedes,int mode)
改变文件权限,可以用
int access (const char *filename,int how)
测试权限。如果只需要文件的时间信息,可以用
int utime (const char *filename,const struct utimbuf *times)
该结构 times 中含有访问时间和修改时间,
int utimes (const char *filename,struct timeval tvp[2])
int lutimes (const char *filename,struct timeval tvp[2])
int futimes (int *fd,struct timeval tvp[2])
将结果存在 sys/time.h 中的 timeval 类型中,l 表示不 follow 符号链接。
使用
int truncate (const char *filename, off_t length)
int ftruncate (int fd, off_t length)
将会截断文件,使用
int mknod (const char *filename,int mode, int dev)
创建一些设备相关的文件,这需要更深入的了解。

11. 下面是一些创建临时文件的函数,可以避免使用固定文件可能造成的问题
FILE * tmpfile (void)
char * tmpnam (char *result)
char * tmpnam_r (char *result)
char * tempnam (const char *dir,const char *prefix)
char * mktemp (char *template)
int mkstemp (char *template)
其中 tmpfile 直接返回了一个 stream,后面的 nam(e) 系列仅仅返回文件名,
长度由 L_tmpnam 控制,tempnam 最强大(设定路径以及前缀),而 mktemp
依照 template 中 XXXX(以之结尾)的个数产生对应的字符串,而 s 版本返回的
是 descriptor 了。 



Windows部分


The I/O functions read and write data to and from files and devices. File I/O operations take place in text mode or binary mode. The Microsoft run-time library has three types of I/O functions:

  • Stream I/O functions treat data as a stream of individual characters.

  • Low-level I/O functions invoke the operating system directly for lower-level operation than that provided by stream I/O.

  • Console and port I/O functions read or write directly to a console (keyboard and screen) or an I/O port (such as a printer port).

    NoteNote

    Because stream functions are buffered and low-level functions are not, these two types of functions are generally incompatible. For processing a particular file, use either stream or low-level functions exclusively.


微软的运行时库,提供了三种类型的I/O操作函数

Stream I/O

These functions process data in different sizes and formats, from single characters to large data structures. They also provide buffering, which can improve performance. The default size of a stream buffer is 4K. These routines affect only buffers created by the run-time library routines, and have no effect on buffers created by the operating system.

Stream I/O Routines

Routine

Use

.NET Framework equivalent

clearerr,clearerr_s

Clear error indicator for stream

Not applicable. To call the standard C function, use PInvoke. For more information, seePlatform Invoke Examples.

fclose

Close stream

System::IO::Stream::Close,System::IO::BinaryReader::Close, System::IO::BinaryWriter::Close, System::IO::TextReader::Close, System::IO::TextWriter::Close, System::IO::StringReader::Close, System::IO::StringWriter::Close, System::IO::StreamReader::Close, System::IO::StreamWriter::Close

_fcloseall

Close all open streams except stdin, stdout, and stderr

System::IO::Stream::Close,System::IO::BinaryReader::Close, System::IO::BinaryWriter::Close, System::IO::TextReader::Close, System::IO::TextWriter::Close, System::IO::StringReader::Close, System::IO::StringWriter::Close, System::IO::StreamReader::Close, System::IO::StreamWriter::Close

_fdopen, wfdopen

Associate stream with file descriptor of open file

System::IO::FileStream::FileStream

feof

Test for end of file on stream

System::IO::FileStream::Read

ferror

Test for error on stream

Not applicable. To call the standard C function, use PInvoke. For more information, seePlatform Invoke Examples.

fflush

Flush stream to buffer or storage device

System::IO::FileStream::Flush

fgetc, fgetwc

Read character from stream (function versions of getc andgetwc)

System::IO::StreamReader::Read

_fgetchar, _fgetwchar

Read character from stdin (function versions ofgetchar and getwchar)

System::Console::Read

fgetpos

Get position indicator of stream

System::IO::FileStream::Position

fgets, fgetws

Read string from stream

System::IO::StreamReader::ReadLine,System::IO::TextReader::ReadBlock

_fileno

Get file descriptor associated with stream

System::IO::FileStream::Handle

_flushall

Flush all streams to buffer or storage device

System::IO::FileStream::Flush,System::IO::StreamWriter::Flush, System::IO::TextWriter::Flush, System::IO::BinaryWriter::Flush

fopen, _wfopen,fopen_s, _wfopen_s

Open stream

System::IO::File::Open

fprintf, _fprintf_l, fwprintf, _fwprintf_l,fprintf_s, _fprintf_s_l, fwprintf_s, _fwprintf_s_l

Write formatted data to stream

System::IO::StreamWriter::Write

fputc, fputwc

Write a character to a stream (function versions of putc andputwc)

System::IO::StreamWriter::Write

_fputchar, _fputwchar

Write character to stdout (function versions ofputchar and putwchar)

System::Console::Write

fputs, fputws

Write string to stream

System::IO::StreamWriter::Write

fread

Read unformatted data from stream

System::IO::FileStream::Read

freopen, _wfreopen,freopen_s, _wfreopen_s

Reassign FILE stream pointer to new file or device

System::IO::File::Open

fscanf, fwscanf,fscanf_s, _fscanf_s_l, fwscanf_s, _fwscanf_s_l

Read formatted data from stream

System::IO::StreamReader::ReadLine; see alsoParse methods, such as System::Double::Parse.

fseek, _fseeki64

Move file position to given location

System::IO::FileStream::Position,System::IO::FileStream::Seek

fsetpos

Set position indicator of stream

System::IO::FileStream::Position

_fsopen, _wfsopen

Open stream with file sharing

Not applicable. To call the standard C function, use PInvoke. For more information, seePlatform Invoke Examples.

ftell, _ftelli64

Get current file position

System::IO::FileStream::Position

fwrite

Write unformatted data items to stream

System::IO::FileStream::Write

getc, getwc

Read character from stream (macro versions of fgetc andfgetwc)

System::IO::StreamReader::Read

getchar, getwchar

Read character from stdin (macro versions offgetchar and fgetwchar)

System::Console::Read

_getmaxstdio

Returns the number of simultaneously open files permitted at the stream I/O level.

Not applicable. To call the standard C function, use PInvoke. For more information, seePlatform Invoke Examples.

gets, getws,gets_s, _getws_s

Read line from stdin

System::Console::Read

_getw

Read binary int from stream

Not applicable. To call the standard C function, use PInvoke. For more information, seePlatform Invoke Examples.

printf, _printf_l, wprintf, _wprintf_l,printf_s, _printf_s_l, wprintf_s, _wprintf_s_l

Write formatted data to stdout

System::Console::Write

putc, putwc

Write character to a stream (macro versions of fputc andfputwc)

System::IO::StreamWriter::Write

putchar, putwchar

Write character to stdout (macro versions offputchar and fputwchar)

System::Console::Write

puts, _putws

Write line to stream

System::Console::Write

_putw

Write binary int to stream

Not applicable. To call the standard C function, use PInvoke. For more information, seePlatform Invoke Examples.

rewind

Move file position to beginning of stream

Not applicable. To call the standard C function, use PInvoke. For more information, seePlatform Invoke Examples.

_rmtmp

Remove temporary files created by tmpfile

Not applicable. To call the standard C function, use PInvoke. For more information, seePlatform Invoke Examples.

scanf, _scanf_l, wscanf, _wscanf_l,scanf_s, _scanf_s_l, wscanf_s, _wscanf_s_l

Read formatted data from stdin

System::Console::ReadLine; see alsoParse methods, such as System::Double::Parse.

setbuf

Control stream buffering

Not applicable. To call the standard C function, use PInvoke. For more information, seePlatform Invoke Examples.

_setmaxstdio

Set a maximum for the number of simultaneously open files at the stream I/O level.

Not applicable. To call the standard C function, use PInvoke. For more information, seePlatform Invoke Examples.

setvbuf

Control stream buffering and buffer size

Not applicable. To call the standard C function, use PInvoke. For more information, seePlatform Invoke Examples.

_snprintf, _snwprintf,_snprintf_s, _snprintf_s_l, _snwprintf_s, _snwprintf_s_l

Write formatted data of specified length to string

Not applicable. To call the standard C function, use PInvoke. For more information, seePlatform Invoke Examples.

_snscanf, _snwscanf,_snscanf_s, _snscanf_s_l, _snwscanf_s, _snwscanf_s_l

Read formatted data of a specified length from the standard input stream.

Not applicable. To call the standard C function, use PInvoke. For more information, seePlatform Invoke Examples.

sprintf, swprintf,sprintf_s, _sprintf_s_l, swprintf_s, _swprintf_s_l

Write formatted data to string

System::String::Format

sscanf, swscanf,sscanf_s, _sscanf_s_l, swscanf_s, _swscanf_s_l

Read formatted data from string

See Parse methods, such as System::Double::Parse

_tempnam, _wtempnam

Generate temporary filename in given directory

Not applicable. To call the standard C function, use PInvoke. For more information, seePlatform Invoke Examples.

tmpfile,tmpfile_s

Create temporary file

Not applicable. To call the standard C function, use PInvoke. For more information, seePlatform Invoke Examples.

tmpnam, _wtmpnam,tmpnam_s, _wtmpnam_s

Generate temporary filename

Not applicable. To call the standard C function, use PInvoke. For more information, seePlatform Invoke Examples.

ungetc, ungetwc

Push character back onto stream

Not applicable. To call the standard C function, use PInvoke. For more information, seePlatform Invoke Examples.

_vcprintf, _vcwprintf,_vcprintf_s, _vcprintf_s_l, _vcwprintf_s, _vcwprintf_s_l

Write formatted data to the console.

System::Console::Write

vfprintf, vfwprintf,vfprintf_s, _vfprintf_s_l, vfwprintf_s, _vfwprintf_s_l

Write formatted data to stream

Not applicable. To call the standard C function, use PInvoke. For more information, seePlatform Invoke Examples.

vprintf, vwprintf,vprintf_s, _vprintf_s_l, vwprintf_s, _vwprintf_s_l

Write formatted data to stdout

System::Console::Write

_vsnprintf, _vsnwprintf,vsnprintf_s, _vsnprintf_s, _vsnprintf_s_l, _vsnwprintf_s, _vsnwprintf_s_l

Write formatted data of specified length to buffer

Not applicable. To call the standard C function, use PInvoke. For more information, seePlatform Invoke Examples.

vsprintf, vswprintf,vsprintf_s, _vsprintf_s_l, vswprintf_s, _vswprintf_s_l

Write formatted data to buffer

System::String::Format


Low-Level I/O

These functions invoke the operating system directly for lower-level operation than that provided by stream I/O. Low-level input and output calls do not buffer or format data.

Low-level routines can access the standard streams opened at program startup using the following predefined file descriptors.

Low-Level I/O Functions

Function

Use

_close

Close file

_commit

Flush file to disk

_creat, _wcreat

Create file

_dup

Return next available file descriptor for given file

_dup2

Create second descriptor for given file

_eof

Test for end of file

_lseek, _lseeki64

Reposition file pointer to given location

_open, _wopen

Open file

_read

Read data from file

_sopen, _wsopen,_sopen_s, _wsopen_s

Open file for file sharing

_tell, _telli64

Get current file-pointer position

_umask,_umask_s

Set file-permission mask

_write

Write data to file


原创粉丝点击