本篇文章主要是讲解在Linux环境下文件IO操作,包含文件IO中的基本概念以及一些常用的函数接口调用,希望可以给读者带来技术上的帮助!
Linux文件的种类:常规文件 -、目录文件 -d 、字符文件 -c 、块文件 -b 、链接文件 -l;
流的概念:就是数据的流,在程序中就是一个结构体;
缓冲区的概念:为了减少操作IO设备的次数,调高运行效率,在内存里设置的缓冲区,分为全缓冲(缓冲区满才输出)和行缓冲(遇到换行符输出);
文件打开:占用资源; 文件关闭:释放资源
文件IO:又称系统IO,系统调用,是操作系统提供的API接口函数。
文件的打开函数:
FILE* fopen(const char* path, const char* mode);
path: 指打开文件的路径,普通文件按当前路径不需要加目录,其他要使用完整路径;
mode:文件的权限(0666);
返回值:出错返回NULL,所以使用fopen函数必须判断是否为空;
文件的打开模式:
文件的关闭函数:
int fclose(FILE* stream);
返回值:调用成功返回0,失败返回EOF(-1),并设置errno;
流关闭时自动刷新缓冲区中的数据并释放缓冲区,比如:常规文件把缓冲区内容写入磁盘;
当一个程序正常终止时,所有打开的流都会关闭;
形参文件流stream必须保证为非空,否则出现错误;
函数:
int fgetc(FILE* stream); //流
int getc(FILE* stream); //宏
int getchar(void); //键盘输入
返回值:成功时返回读取的字符,到文件末尾或出错时返回EOF(-1);
getchar()等同于 fgetc(stdin);
getc和fget区别是一个宏一个函数;
注意事项:
(1)函数返回值是int类型不是char类型,主要是为了扩展返回值的范围;
(2)stdin也是FILE*的指针,是系统定义好的,指向的是标准输入(键盘输入);
(3)打开文件按后读取,是从文件开头读,读完一个后读写指针会后移,读写注意指针的位置。
(4)调用getchar会阻塞,等待你的键盘输入;
函数:
int fputc(int c, FILE* stream); //流
int putc(int c, FILE* stream); //流
int putchar(int c); //屏幕
行输入(读取整行)get
函数:
char* gets(char *s); //读取标准输入到缓冲区s,键盘
char* fgets(char *s, int size, FILE* stream); //stream
返回值:成功时返回缓冲流s,到文件末尾会出错时返回NULL;
注意事项:
(1)gets函数已经被淘汰,因为会导致缓冲区溢出;
(2)fgets 函数第二个参数,输入的数据超出size,size-1个字符会保存到缓冲区里,并且在最后面加'\0‘ ,如果输入数据少于size-1 后面会添加换行符;
行输出(写整行)
函数:
int puts(const char *s);
int fputs(const char* s, FILE* stream);
返回值:成功时返回非负整数,出错时返回EOF;
注意事项:
puts 将缓冲区s中的字符串输出到stdout,并追加'\n';
fputs 将缓冲区s中的字符串输出到stream,不追加’\n‘;
函数:
读
size_t fread(void *ptr, size_t size, size_t n, FILE *fp);
void *ptr 读取内容放的位置指针
size_t size 读取的块大小
size_t n 读取的个数
FILE *fp 读取的文件指针
写
size_t fwrite(const void *ptr, size_t size, size_t n, FILE *fp);
void *ptr 写文件的内容的位置指针
size_t size 写的块大小
size_t n 写的个数
FILE *fp 要写的文件指针
注意事项:
文件写完后,文件指针指向文件末尾,如果这时候读,读不出来内容;
解决办法:移动指针到头文件(重定位);关闭文件,重新打开;
int fflush(FILE* fp);
返回值:成功时返回0,出错时放回EOF;
将流缓冲区中的数据写入实际的文件;
Linux下只能刷新输出缓冲区,输入缓冲区丢弃;
如果输出到屏幕使用fflush(stdout);
函数:
long ftell(FILE* stream);
void rewind(FILE* stream);
long fseek(FILE* stream,long offset, int whence);
参数:
whence:SEEK_SET/SEEK_CUR/SEEK_END
SEEK_SET 从距文件开头 offset 位移量为新的读写位置
SEEK_CUR:以目前的读写位置往后增加 offset 个位移量
SEEK_END:将读写位置指向文件尾后再增加 offset 个位移量
offset:偏移量,可正可负
注意事项:
(1)文件的打开使用a模式fseek无效;
(2)rewind(fp)相当于fseek(fp,0,SEEK_SET);
(3)这三个函数只适用于2G以下的文件;
格式化输出:
int fprintf(FILE* stream,const char *fmt,...);
int sprintf(char* s,const char* fmt,.....);
返回值:成功时返回输出的字符个数;出错时返回EOF;
格式化输入:
int fscanf(FILE* stream,const char *format,...);
int sscanf(const char *str,const char* format,..);
重点掌握sprintf和sscanf;
文件IO不提供缓冲机制
文件IO的API:open close read read
文件描述符概念:
英文:缩写fd(file descriptor)
是0-1023的数字,表示文件。
0, 1, 2 的含义 标准输入,标准输出,错误。
open
int open (const char* pathname,int flags); //不创建文件
Int open(const char* pathname,int flags,mode_t mode); //创建文件,不能创建设备文件成功时返回文件描述符;出错时返回EOF
文件IO和标准的模式对应关系:
r O_RDONLY
r+ O_RDWR
w O_WRONLY | O_CREAT | O_TRUNC, 0664
w+ O_RDWR | O_CREAT | O_TRUNC, 0664
a O_WRONLY | O_CREAT | O_APPEND, 0664
a+ O_RDWR | O_CREAT | O_APPEND, 0664
close
int close(int fd);
关闭后文件描述符不能代表文件;
read
函数:
ssize_t read(int fd,void * buf, size_t count);
返回值:成功时返回实际读取的字节数,出错时返回EOF;读到文件末尾是返回0;
参数:buf是接收数据的缓冲区;count不应超过buf大小;
write
函数:
ssize_t write(int fd,void *buf,size_t count);
返回值:成功时返回实际写入的字节数,出错时返回EOF;
参数:buf是接收数据的缓冲区;count不应超过buf大小;
lseek
函数:
off_t lseek(int fd,off_t offset,intt whence);
返回值:成功时返回当前的文件读写位置;出错时返回EOF;
参数:offsethe whence同fseek完全一样;
函数:
DIR* opendir(const char* name);
DIR* fdopendir(int fd); //使用文件描述符,要配合open函数使用
DIR是用来描述一个打开的目录文件的结构体类型,类似于FILE;
返回值:成功时返回目录流指针(DIR*);出错时返回NULL;
函数:
struct dirent* readdir(DIR* dirp);
struct dirent是用来藐视目录流中一个目录项的结构体类型,包含成员char d_name[256]
返回值:成功时返回目录流dirp中下一个目录项;出错或末尾时返回NULL;
函数
#include <dirent.h>
int closedir(DIR *dirp);
返回值:成功时返回0;出错时返回EOF
函数:
#include <sys/stat.h>
int chmod(const char *path, mode_t mode);
int fchmod(int fd, mode_t mode);
成功时返回0;出错时返回EOF
注意:在vmware和windows共享的文件夹下,有些权限不能改变。
函数:
#include <sys/stat.h>
int stat(const char *path, struct stat *buf);
int lstat(const char *path, struct stat *buf);
int fstat(int fd, struct stat *buf);
返回值:成功时返回0;出错时返回EOF
如果path是符号链接stat获取的是目标文件的属性;而lstat获取的是链接文件的属性
创建步骤:
(1)编写库文件代码,编译为.o 目标文件。
(2)ar 命令 创建 libxxxx.a 文件
ar -rsv libxxxx.a xxxx.o
注意: 静态库名字要以lib开头,后缀名为.a
没有main函数的.c 文件不能生成可执行文件。
链接错误:
test.c:(.text+0x15):对‘hello’未定义的引用
collect2: error: ld returned 1 exit status
含义:表示hello函数在编译的源码内没有找到实现
解决:实现代码或者找到对应函数的库并且链接它。
链接静态库:
gcc -o 目标文件 源码.c -L路径 -lxxxx
-L 表示库所在的路径
-l 后面跟库的名称
创建步骤:
(1)生成位置无关代码的目标文件
gcc -c -fPIC xxx.c xxxx.c ....
(2)生成动态库
gcc -shared -o libxxxx.so xxx.o xxx.o ....
(3)编译可执行文件
gcc -o 目标文件 源码.c -L路径 -lxxxx
可执行文件错误:
./test: error while loading shared libraries: libmyheby.so: cannot open shared object file: No such file or directory
含义:可执行文件所使用的动态库找不到
解决办法:
找到动态库,添加到/usr/lib里面
或者使用export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:你的动态库目录
添加在~/.bashrc 文件里面,使用source ~/.bashrc 生效。
本文讲解了三种类型IO操作以及库,三种类型分别是标准IO、文件IO以及目录,三者既有不同点又有相同点。三种都有打开、读写及关闭,对于标准IO来说,每个函数前以字母f打头(fopen\fclose\fseek等),文件IO则是直接open、close,目录得在后面加上dir来区别,并且标准IO有结构体类型的文本流FILE,文件IO有int类型的文本描述符f,目录则是由结构体类型的目录流DIR。
文章浏览阅读1.5k次。对于一般的包,直接File->Settings->Project Interpreter->点加号搜名字就行了但是在安装seaborn的时候,总是提示出错,问题可能在于seaborn要依赖于scipy,但是装seaborn的时候他不给你装scipy,只能手动去装,于是我就去一个网站下载了scipy:http://www.lfd.uci.edu/~gohlke/pythonlibs/#sci_import helper出错
文章浏览阅读1.3k次,点赞3次,收藏11次。大学生网页代码,静态动态都可以做,这是我随手做的球星库里的网页_库里的html动态网页
文章浏览阅读467次。原文地址:http://blog.csdn.net/hekunhotmail/article/details/9302541以下是我常用到的svn 命令行,整理了一下,这东西版本控制上很有用,所以不会不行,当然,你也可以选择一些svn图形界面的工具0 查看当前工作目录svn 状态简写:svn st1、将文件checkout到本地目录svn checkout path(path是_svn命令 显示修改列表
文章浏览阅读834次。MySQLDECIMAL数据类型用于在数据库中存储精确的数值。我们经常将DECIMAL数据类型用于保留准确精确度的列,例如会计系统中的货币数据。要定义数据类型为DECIMAL的列,请使用以下语法:column_name DECIMAL(P,D);在上面的语法中:P是表示有效数字数的精度。P范围为1〜65。D是表示小数点后的位数。D的范围是0~30。MySQL要求D小于或等于(<=)P。DEC..._mysql decimal 保存成整数
文章浏览阅读750次。文章目录一、官网1. Products (产品介绍)2. Dev Center (开发者中心)(1)Getting Started(入门教程)(2)Tutorials(教程)(3)Documentation(文档)(4)Download & Help(下载和帮助)总结一、官网官网地址是 https://www.genivia.com/,主页很简单。接下来看一下主要内容。1. Products (产品介绍)最先进的C/XC++自动编码工具是XML Web服务API和其他XML应用程序,是_gsoap download
文章浏览阅读796次。现象是:依次加载了总线bus,设备device,驱动driver,在加载驱动时候出现了segmentation fault。环境条件:采用的是国嵌的教材(可能是教材比较古老了吧,导致出现这样问题),内核版本使用的是2.6.32.2。最后查找原因是由于空指针导致了在strncmp产生了段错误。_struct device init_name
文章浏览阅读27次。作为参数,0表示第一行,1表示第2行,以此类推。DataFrame意为数据框架,是Pandas库中的一种数据结构,类似于二维表,由行和列组成,与Series一样支持多种数据类型。loc属性,以列名(columns)和行名(index)作为参数,当只有一个参数时,默认是行名,即抽取整行数据,包括所有列。修改行标题,使用DataFrame对象的index属性直接赋值,,或者使用DataFrame对象的rename方法修改行标题。缺失值的处理方式有不处理、删除、填充或替换、插值(均值、中位数、众数等填补)_pandas基础
文章浏览阅读3.1k次。方式一 一些坑提醒 项目中含有中文,那么请全局设置utf-8编码或者,使用另一种方式生成JavaDoc(可以仔细看下方生成JavaDoc方式,不一样的) 上传的库的名字,是和你Module的名字是一样的!!!所以你的Module叫什么,你的gradle依赖路径就是: groupId:moduleName:publishVersion 下面的步骤只是将项目提交到Maven里面,你要在提交完成后_publication not found
文章浏览阅读1.1k次,点赞21次,收藏25次。v= zk - hx 在代码中对应的是v[nv]=y-(r+cdtr-CLIGHT*dts[i*2]+dtrp+C*dion+dcb+bias);9) ppp_res(9,obs,n,rs,dts,var,svh,dr,exc,nav,xp,rtk,v,H,R,azel)) 模糊度固定的残差校验。kalman方程中的测量xk = xk/k-1 +kv 以及pk = pk/k-1 - kh*pk/k-1 状态更新。待估参数的预测,对应klaman公式中的xk/k-1、 Pk/k-1。_rtklib进行ppp解算
文章浏览阅读60次。SVG 是可缩放矢量图形的缩写,它是一种用于描述二维矢量图形的XML标记语言。与传统的栅格图像不同,SVG图像可以无限缩放而不会失真,同时也支持交互和动画等特性。SVG最早于1999年由W3C发布,用于在Web上展示矢量图形,并于2001年正式成为标准。在过去的二十多年中,SVG经历了多次更新和改进,增加了更多的功能和特性,如动画、交互等,并逐渐得到广泛的应用。SVG2.0于2016年9月15日成为W3C候选推荐标准,最新草案于。_如何训练svg标注数据集
文章浏览阅读1.5k次,点赞4次,收藏11次。Windows 端CUDA10.2+CUDNN8环境搭建for Pytorch1.71.CUDA下载安装1.1 查看自己的显卡1.2 显卡驱动下载及安装1.3 显卡驱动安装检测1.4 CUDN下载1.5 CUDN安装1.6 环境变量设置2 CUDNN安装2.1 CUDNN下载2.2 CUDNN安装2.3 CUDA安装检测最近,我做了一些使用YOLOV5算法的项目,遇到了很多的坑,也感叹YOLOV5的人性化操作,如此真香的算法,忍不住拿出来与大家进行分享,现在就把项目过程中的一些操作逐个记录一遍。很不好意_cudnn8
文章浏览阅读6.7k次。 1. 修改dfs.datanode.max.transfer.threads = 4096 (如果运行hbase的话建议为16384),指定用于在DataNode间传输block数据的最大线程数,老版本的对应参数为dfs.datanode.max.xcievers2. 修改dfs.datanode.balance.bandwidthPerSec = 52428800,指定DataNod..._failed to move blk_1076014847_2274553 with size=89971516 from 172.16.33.248: