Linux/Unix 下对文件操作的学习

---------------------------------
open, read, write, close 的基础使用

一个概念: 文件描述符 file descriptor, int 型的,用来与要操作的文件相关联
通常有三个值是默认的:
0 标准输入
1 标准输出
2 标准错误

打开文件的过程,就是将文件于一个文件描述符相关联:
int open(const char *path, int oflags);
int open(const char *path, int oflags, mode_t mode);
输入 要打开的或者要新建的文件路径 path, 设置读写的方式 oflags(只读,只写,读写),如果是新建一个文件,那么还可以设置文件权限 mode。
打开成功返回 int 文件描述符

读文件
size_t read(int fildes, void *buf, size_t nbytes);
输入参数 open出来的文件描述符 fildes, 从 fildes 中读取 nbytes 的Byte 到 buf 中去,返回值是成功读到的字节数,如果失败返回 -1

写文件
size_t write(int fildes, const void *buf, size_t nbytes);
和读文件差不多的,从 buf 里面读去 nbyes 的字节,到 fildes 所代表的文件中。返回实际写入的字节数

关闭
int close(int fildes);
关闭打开的文件描述符 fildes

以上是最最基本的操作,已经可以写个小程序来自己实践一下了:
实践描述
:一个文件拷贝程序,把一个文件里的内容,拷贝到一个新的文件里去


以下是使用时要注意的一些问题,不全

open

- 注意打开的文件的读写属性,不要去写 只读的 CD-ROM 设备
- 第二个参数 oflags 还可以组合一些设置,常用的有 O_TRUNC(删掉原文件里的内容), O_APPEND(跟在原文件后面写), O_CREAT, O_CREAT|O_EXCL(强制新建文件,如果已经存在,则open失败)
- 如果使用了 O_CREAT, 就在第三个可选参数中表明新文件的权限
- 打开文件描述符占用内核资源,因此一个进程里可同时打开的文件描述符也有上限,通常为 1024 个 setrlimit 函数可以改变这个值

close

- 对于不同的设备,close 导致的行为也不一样的: 对于 close 一个 socket 而言,所做得操作就是断开两台电脑之间的 socket 网络 ...

以下 from APUE

read

- 有多种情况可使实际读到的字节数少于要求读字节数:
• 读普通文件时,在读到要求字节数之前已到达了文件尾端。例如,若在到达文件尾端之前还有3 0个字节,而要求读1 0 0个字节,则read返回3 0,下一次再调用read时,它将返回0 (文件尾端)。
• 当从终端设备读时,通常一次最多读一行(第11章将介绍如何改变这一点)。
• 当从网络读时,网络中的缓冲机构可能造成返回值小于所要求读的字节数。
• 某些面向记录的设备,例如磁带,一次最多返回一个记录。

- 读操作从文件的当前位移量处开始,在成功返回之前,该位移量增加实际读得的字节数。

write

- write出错的一个常见原因是:磁盘已写满,或者超过了对一个给定进程的文件长度限制
- 对于普通文件,写操作从文件的当前位移量处开始。如果在打开该文件时,指定了O_APPEND选择项,则在每次写操作之前,将文件位移量设置在文件的当前结尾处。在一次成功写之后,该文件位移量增加实际写的字节数。


文件的属性 - 文件权限的设置

上面提到的用 open 函数打开文件的时候,可以在第二个参数里设置文件的读写方式,如果是新建文件,还可以在第三个参数中设置文件的权限。

int open(const char *path, int oflags, mode_t mode);

关于 oflags 的常用设置

首先,O_RDONLY(只读)、O_WRONLY(只写)、O_RDWR(可读可写) 三各种必须选择一个,通常这也是最简单的设置了。
注意这些设置还要考虑到所选文件或设备的权限,属性,对只读文件进行可读可写设置是没有什么意义的

还有一些常用的选项:

O_TRUNC - 如果是打开已经存在的文件,此选项将新写入的内容替代掉原来的内容
O_APPEND - 新写入的内容,将跟在原来内容的后面
O_CREAT - 如果要打开的文件不存在,则创建此文件,注意,要确保文件创建的路径存在,且允许在此文件夹下新建文件
O_CREAT | O_EXCL - 强制新建文件,如果文件已经存在,则 open 函数返回失败。

这里还补充一个不常用的调用: create 函数
其实就相当于 open 函数带上 O_CREAT|O_WRONLY|O_TRUNC.

关于 mode 设置

使用 O_CREAT 创建的文件,需要对第三个可选参数进行一些权限设置
如果有一些linux/UNIX 下文件权限的知识呢,这个设置就比较好理解了

S_IRUSR: Read permission, owner
S_IWUSR: Write permission, owner
S_IXUSR: Execute permission, owner
S_IRGRP: Read permission, group
S_IWGRP: Write permission, group
S_IXGRP: Execute permission, group
S_IROTH: Read permission, others
S_IWOTH: Write permission, others
S_IXOTH: Execute permission, others

eg: open ("hello.txt", O_CREAT, S_IRUSR|S_IXOTH);
这个设置就把 hello.txt 的权限设置为 文件所有者有读权限,其他每个人都有执行的权限 —— 此文件有且仅有此两项权限


上面提到了流式文件操作与非流式文件操作,以及它们之间的转换
非流式的文件操作,也就是常用的f开头的,如 fopen, fread 等等函数,这里不再赘述,说说两者的转换:

文件描述符和文件指针的转换

使用两个函数,可以轻松实现两者的转换关系,这在一些场合(有时候用流式函数方便,但有时候有需要用文件描述符函数做些底层工作)还是很有用的。

int fileno(FILE *stream);

The function fileno examines the argument stream and returns its integer descriptor.

FILE *fdopen(int fildes, const char *mode);
FILE *freopen(const char *path, const char *mode, FILE *stream);

使用的时候,还是有些注意点的~

fdopen 函数,将一个文件指针与 fildes 的文件描述符相联系, mode 参数的值( "r", "r+", "w", "w+", "a", "a+")),要与 fildes 所代表文件的读写权限一致
在 fdopen 里设置 "w" "w+" 并不会象 fopen 那样,截断已存在的数据,还是会接着尾端写。

此函数常用于由创建管道和网络通信通道函数获得的插述符。因为这些特殊类型的文件不能用标准I/O fopen函数打开,首先必须先调用设备专用函数以获得一个文件描述符,然后用fdopen使一个标准I/O流与该描述符相结合。
freopen在一个特定的流上(由f p指示)打开一个指定的文件(其路径名由pathname 指示),如若该流已经打开,则先关闭该流。此函数一般用于将一个指定的文件打开为一个预定义的流:标准输入、标准输出或标准出错。


接下来讲讲流式I/O读写控制中,对缓冲区的控制方式

有三种类型:
全缓冲, 行缓冲, 无缓冲

全缓冲 (block buffer): 也就是说保存下要发送的数据,直到填满一个块,在一起发出去;通常的文件读写使用的都是全缓冲方式
行缓冲: 也就是接受到换行符,才进行读写;常见的用于标准输入stdin,标准输出stdout
无缓冲: 无缓冲机制,收到一个,就读写一个;常见的如标准出错流 stderr

可以使用以下函数改变文件流的缓冲方式

int setvbuf(FILE *stream, char *buf, int mode , size_t size);
mode 可以是:
_IONBF unbuffered 无缓冲
_IOLBF line buffered 行缓冲
_IOFBF fully buffered 全缓冲

setvbuf 必须在 open 了文件而没有进行其他文件操作前使用

强制刷新流使用 fflush 函数,可以是缓冲区中的数据立即写入文件

int fflush(FILE *stream);


文件的定位:

底层 I/O 使用:

off_t lseek(int fildes, off_t offset, int whence);

此系统调用,对文件描述符的读写指针进行设置,结合offset 和 whence 来确定这个位置。

whence 定义了 offset 偏移值的用法
SEEK_SET offset 是个绝对位置
SEEK_CUR offset 是从当前指针位置算起的相对位置
SEEK_END offset 是从文件尾算起的位置。

lseek 返回值是从文件头算起到设置出的偏移值。

off_t 类型定义在 sys/types.h 里

-----------------------

定位标准I/O流:

ftell
fseek


对于二进制文件,位置指示从开始处计算,以字节为单位;
QUOTE
对于文本文件,它们的文件当前位置可能不以简单的字节位移量来度量。再一次,这主要
也是在非U N I X系统中,它们可能以不同的格式存放文本文件。为了定位一个文本文件,
whence一定要是SEEK_SET,而且offset只能有两种值: 0(表示反绕文件至其起始位置),或是对该文件的ftell所返回的值。使用rewind函数也可将一个流设置到文件的起始位置。

当程序可能需要移植到非 unix 系统上时,要使用 fgetpos 和 fsetpos


whence 定义了 offset 偏移值的用法
SEEK_SET offset 是个绝对位置
SEEK_CUR offset 是从当前指针位置算起的相对位置
SEEK_END offset 是从文件尾算起的位置。

lseek 返回值是从文件头算起到设置出的偏移值。


偶觉得会不会是ms文本文件的保存方式与unix不同

unix无论怎样 都是保存成二进制文件 不去处理里面的内容

而ms保存时会把rn转换成n 读出来时再把n转换成rn 如果按文本文件打开的话 (难道以前考虑节省用户磁盘空间)


fseek在windows下还是看看msdn说明 看它是针对内存中的流进行寻址还是针对磁盘上文件进行寻址 或是自己写个小程序试试


fstat stat 和 lstat 系统调用

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

int fstat(int fildes, struct stat *buf);
int stat(const char *path, struct stat *buf);
int lstat(const char *path, struct stat *buf);

fstat 函数可以获得与 fildes 相关联的文件的信息.
三个函数的第二个参数均是 stat 结构的,stat 在不同unix系统中有所不同,主要可以获得一些 文件权限,类型,访问时间,文件身份标示等等的信息。
其中涉及一些宏定义,可在 sys/types.h 中找到

例子:

struct stat statbuf;
mode_t modes;

stat("filename", &statbuf);
modes = statbuf.st_mode;


fcntl 可以用来改变文件的很多属性,如复制,获取和设置文件描述符,改变文件状态,文件加锁。

#include <fcntl.h>

int fcntl(int fildes, int cmd);
int fcntl(int fildes, int cmd, long arg);

fildes 就是要操作的文件描述符
cmd 决定对 fildes 进行什么样的操作

APUE:
fcntl 函数有五种功能
• 复制一个现存的描述符(cmd=F_DUPFD)。—— 功能类似于 dup/dup2 但还是有些细节区别的;
• 获得/设置文件描述符标记(cmd = F_GETFD或F_SETFD)。
• 获得/设置文件状态标志(cmd = F_GETFL或F_SETFL)。
• 获得/设置异步I / O有权(cmd = F_GETOWN或F_SETOWN)。
• 获得/设置记录锁(cmd = F_GETLK , F_SETLK或F_SETLKW)。




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
智慧校园信息化系统解决方案旨在通过先进的信息技术,实现教育的全方位创新和优质资源的普及共享。该方案依据国家和地方政策背景,如教育部《教育信息化“十三五”规划》和《教育信息化十年发展规划》,以信息技术的革命性影响为指导,推进教育信息化建设,实现教育思想和方法的创新。 技术发展为智慧校园建设提供了强有力的支撑。方案涵盖了互连互通、优质资源共享、宽带网络、移动APP、电子书包、电子教学白板、3D打印、VR虚拟教学等技术应用,以及大数据和云计算技术,提升了教学数据记录和分析水平。此外,教育资源公共服务平台、教育管理公共服务平台等平台建设,进一步提高了教学、管控的效率。 智慧校园系统由智慧教学、智慧管控和智慧办公三大部分组成,各自具有丰富的应用场景。智慧教学包括微课、公开课、精品课等教学资源的整合和共享,支持在线编辑、录播资源、教学分析等功能。智慧管控则通过平安校园、可视对讲、紧急求助、视频监控等手段,保障校园安全。智慧办公则利用远程视讯、无纸化会议、数字会议等技术,提高行政效率和会议质量。 教育录播系统作为智慧校园的重要组成部分,提供了一套满足学校和教育局需求的解决方案。它包括标准课室、微格课室、精品课室等,通过自动五机位方案、高保真音频采集、一键式录课等功能,实现了优质教学资源的录制和共享。此外,录播系统还包括互动教学、录播班班通、教育中控、校园广播等应用,促进了教育资源的均衡化发展。 智慧办公的另一重点是无纸化会议和数字会议系统的建设,它们通过高效的文件管理、会议文件保密处理、本地会议的音频传输和摄像跟踪等功能,实现了会议的高效化和集中管控。这些系统不仅提高了会议的效率和质量,还通过一键管控、无线管控等设计,简化了操作流程,使得会议更加便捷和环保。 总之,智慧校园信息化系统解决方案通过整合先进的信息技术和教学资源,不仅提升了教育质量和管理效率,还为实现教育均衡化和资源共享提供了有力支持,推动了教育现代化的进程。
智慧校园信息化系统解决方案旨在通过先进的信息技术,实现教育的全方位创新和优质资源的普及共享。该方案依据国家和地方政策背景,如教育部《教育信息化“十三五”规划》和《教育信息化十年发展规划》,以信息技术的革命性影响为指导,推进教育信息化建设,实现教育思想和方法的创新。 技术发展为智慧校园建设提供了强有力的支撑。方案涵盖了互连互通、优质资源共享、宽带网络、移动APP、电子书包、电子教学白板、3D打印、VR虚拟教学等技术应用,以及大数据和云计算技术,提升了教学数据记录和分析水平。此外,教育资源公共服务平台、教育管理公共服务平台等平台建设,进一步提高了教学、管控的效率。 智慧校园系统由智慧教学、智慧管控和智慧办公三大部分组成,各自具有丰富的应用场景。智慧教学包括微课、公开课、精品课等教学资源的整合和共享,支持在线编辑、录播资源、教学分析等功能。智慧管控则通过平安校园、可视对讲、紧急求助、视频监控等手段,保障校园安全。智慧办公则利用远程视讯、无纸化会议、数字会议等技术,提高行政效率和会议质量。 教育录播系统作为智慧校园的重要组成部分,提供了一套满足学校和教育局需求的解决方案。它包括标准课室、微格课室、精品课室等,通过自动五机位方案、高保真音频采集、一键式录课等功能,实现了优质教学资源的录制和共享。此外,录播系统还包括互动教学、录播班班通、教育中控、校园广播等应用,促进了教育资源的均衡化发展。 智慧办公的另一重点是无纸化会议和数字会议系统的建设,它们通过高效的文件管理、会议文件保密处理、本地会议的音频传输和摄像跟踪等功能,实现了会议的高效化和集中管控。这些系统不仅提高了会议的效率和质量,还通过一键管控、无线管控等设计,简化了操作流程,使得会议更加便捷和环保。 总之,智慧校园信息化系统解决方案通过整合先进的信息技术和教学资源,不仅提升了教育质量和管理效率,还为实现教育均衡化和资源共享提供了有力支持,推动了教育现代化的进程。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值