四、基于文件指针的文件操作

基于文件指针的文件操作(缓冲)

linux的文件和文件描述符

linux中对目录和设备的操作都是文件操作,文件分为普通文件,目录文件,链接文件和设备文件

普通文件:也称磁盘文件,并且能够进行随机的数据存储(能够自由seek定位到某一个位置);

管道:是一个从一端发送数据,另一端接收数据的数据通道;

目录:也称为目录文件,它包含了保存在目录中文件列表的简单文件。

设备:该类型的文件提供了大多数物理设备的接口。它又分为两种类型:字符型设备和块设备。

字符型设备一次只能读出和写入一个字节的数据,包括调制解调器、终端、打印机、声卡以及鼠标;

块设备必须以一定大小的块来读出或者写入数据,块设备包括CD-ROM、RAM驱动器和磁盘驱动器等,一般而言,字符设备用于传输数据,块设备用于存储数据。

 链接:类似于Windows的快捷方式和Linux里的别名,指包含到达另一个文件路径的文件。

套接字:在Linux中,套接字也可以当作文件来进行处理。

基于文件指针的文件操作函数是ANSI标准函数库的一部分。

1文件的创建,打开与关闭

原型为:

#include <stdio.h>  //头文件包含

FILE *fopen(const char *pach,const char *mode);  //文件名  模式

int fclose(FILE *stream);

fopen以mode的方式打开或创建文件,如果成功,将返回一个文件指针,失败则返回NULL.

fopen创建的文件的访问权限将以0666与当前的umask结合来确定。

mode的可选模式列表


模式




位置


截断原内容


创建


rb


Y


N


文件头


N


N


r+b


Y


Y


文件头


N


N


wb


N


Y


文件头


Y


Y


w+b


Y


Y


文件头


Y


Y


ab


N


Y


文件尾


N


Y


a+b


Y


Y


文件尾


N


Y

在Linux系统中,mode里面的’b’(二进制)可以去掉,但是为了保持与其他系统的兼容性,建议不要去掉。ab和a+b为追加模式,在此两种模式下,无论文件读写点定位到何处,在写数据时都将是在文件末尾添加,所以比较适合于多进程写同一个文件的情况下保证数据的完整性。

2 读写文件

基于文件指针的数据读写函数较多,可分为如下几组:

数据块读写:

#include <stdio.h>

size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);

size_t fwrite(void *ptr, size_t size, size_t nmemb, FILE *stream);

fread从文件流stream 中读取nmemb个元素,写到ptr指向的内存中,每个元素的大小为size个字节。

fwrite从ptr指向的内存中读取nmemb个元素,写到文件流stream中,每个元素size个字节。

所有的文件读写函数都从文件的当前读写点开始读写,读写完以后,当前读写点自动往后移动size*nmemb个字节。

格式化读写:

#include <stdio.h>

int printf(const char *format, ...);                   //相当于 fprintf(stdout,format,…);

int scanf(const char *format, …);

int fprintf(FILE *stream, const char *format, ...);

int fscanf(FILE *stream, const char *format, …);

int sprintf(char *str, const char *format, ...);          // eg:   sprintf(buf,”the string is;%s”,str);

int sscanf(char *str, const char *format, …);

以f开头的将格式化后的字符串写入到文件流stream中

以s开头的将格式化后的字符串写入到字符串str中

单个字符读写:

使用下列函数可以一次读写一个字符

#include <stdio.h>

int fgetc(FILE *stream);

int fputc(int c, FILE *stream);

int getc(FILE *stream);    //等同于 fgetc(FILE* stream)

int putc(int c, FILE *stream);   // 等同于 fputc(int c, FILE* stream)

int getchar(void);    //等同于 fgetc(stdin);

int putchar(int c);    // 等同于 fputc(int c, stdout);

getchar和putchar从标准输入输出流中读写数据,其他函数从文件流stream中读写数据。

字符串读写:

char *fgets(char *s, int size, FILE *stream);

int fputs(const char *s, FILE *stream);

int puts(const char *s);// 等同于 fputs(const char *s, int size, stdout);

char *gets(char *s);     // 等同于 fgets(const char *s, int size,stdin);

fgets和fputs从文件流stream中读写一行数据;

puts和gets从标准输入输出流中读写一行数据。

fgets可以指定目标缓冲区的大小,所以相对于gets安全,但是fgets调用时,如果文件中当前行的字符个数大于size,则下一次fgets调用时,将继续读取该行剩下的字符,fgets读取一行字符时,保留行尾的换行符

fputs不会在行尾自动添加换行符,但是puts会在标准输出流中自动添加一换行符

文件定位:

文件定位指读取或设置文件当前读写点,所有的通过文件指针读写数据的函数,都是从文件的当前读写点读写数据的。

常用的函数有:

#include <stdio.h>

int feof(FILE * stream);   //通常的用法为while(!feof(fp))

int fseek(FILE *stream, long offset, int whence);//设置当前读写点到偏移whence 长度为offset处

long ftell(FILE *stream); //用来获得文件流当前的读写位置

void rewind(FILE *stream); //把文件流的读写位置移至文件开头 fseek(fp, 0, SEEK_SET);

feof判断是否到达文件末尾的下一个(注意到达文件末尾之后还会做一次)

fseek设置当前读写点到偏移whence 长度为offset处,whence可以是:

SEEK_SET (文件开头  ->0)

SEEK_CUR (文件当前位置  ->1)

SEEK_END (文件末尾  ->2)

ftell获取当前的读写点

rewind将文件当前读写点移动到文件头

注:基于文件指针的文件操作请参考《C语言文件操作常用函数详解.doc》

3目录操作

改变目录或文件的访问权限

#include <sys/stat.h>

int chmod(const char* path, mode_t mode); //mode形如:0777

path参数指定的文件被修改为具有mode参数给出的访问权限。

获取、改变当前目录:

原型为:

#include <unistd.h>   //头文件

char *getcwd(char *buf, size_t size); //获取当前目录,相当于pwd命令

int chdir(const char *path); //修改当前目录,即切换目录,相当于cd命令

其中getcwd()函数:将当前的工作目录绝对路径复制到参数buf所指的内存空间,参数size为buf的空间大小. 在调用此函数时,buf所指的内存空间要足够大,若工作目录绝对路径的字符串长度超过参数size大小,则回值NULL,errno的值则为ERANGE。

倘若参数buf为NULL,getcwd()会依参数size的大小自动配置内存(使用malloc()),如果参数size也为0,则getcwd()会依工作目录绝对路径的字符串程度来决定所配置的内存大小,进程可以在使用完此字符串后自动利用free()来释放此空间。所以常用的形式:getcwd(NULL, 0);

chdir()函数:用来将当前的工作目录改变成以参数path所指的目录

Example:

1 #include<unistd.h>
2 int main()
3 {
4
5   chdir(“/tmp”);
6   printf(“current working directory: %s\n”,getcwd(NULL,0));
7       return 0;
8
9 }

创建和删除目录:

原型为:

#include <sys/stat.h>

#include <sys/types.h>

#include <unistd.h>

int mkdir(const char *pathname, mode_t mode); //创建目录,mode是目录权限,没用

int rmdir(const char *pathname); //删除目录

获取目录信息:

原型为:

#include <sys/types.h>

#include <dirent.h>

DIR *opendir(const char *name); //打开一个目录,返回一个目录流

struct dirent *readdir(DIR *dir); //读取目录的一项信息,并返回该项信息的结构体指针

void rewinddir(DIR *dir); //重新定位到目录文件的头部

void seekdir(DIR *dir,off_t offset);//用来设置目录流目前的读取位置

off_t telldir(DIR *dir); //返回目录流当前的读取位置

int closedir(DIR *dir); //关闭目录文件

读取目录信息的步骤为:

1 用opendir函数打开目录;

2使用readdir函数迭代读取目录的内容,如果已经读取到目录末尾,又想重新开始读,则可以使用rewinddir函数将文件指针重新定位到目录文件的起始位置;

3 用closedir函数关闭目录

opendir()用来打开参数name指定的目录,并返回DIR*形态的目录流,和文件操作函数open()类似,接下来对目录的读取和搜索都要使用此返回值。函数失败则返回NULL;

readdir()函数用来读取目录的信息,并返回一个结构体指针,该指针保存了目录的相关信息。有错误发生或者读取到目录文件尾则返回NULL;dirent结构体如下:

struct dirent

{

  ino_t  d_ino;           /* inode number(此目录进入点的inode) */

  off_t  d_off;             /* offset to the next dirent(目录开头到进入点的位移 */

  unsigned short d_reclen;  /* length of this record(目录名的长度) */

  unsigned char d_type;     /* type of file(所指的文件类型) */

  char   d_name[256];       /* filename(文件名) */

};

seekdir()函数用来设置目录流目前的读取位置,再调用readdir()函数时,便可以从此新位置开始读取。

参数offset代表距离目录文件开头的偏移量。

telldir()函数用来返回目录流当前的读取位置。

示例:返回指定目录下的文件

 1 #include <stdio.h>
 2
 3 #include <sys/types.h>
 4
 5 #include <dirent.h>
 6
 7
 8
 9 int main(int argc,char *argv[])
10
11 {
12
13     struct dirent *pDirInfo;
14
15     DIR *pDir;
16
17     if(argc < 2)
18
19         pDir = opendir(".");
20
21     else
22
23         pDir = opendir(argv[1]);
24
25 if(NULL == pDir)
26
27 {
28
29         perror("open dir fail!");
30
31         return -1;
32
33     }
34
35     while( (pDirInfo = readdir(pDir)) != NULL )
36
37         printf("%s\n",pDirInfo->d_name);
38
39       closedir(pDir);
40
41         return 0;
42
43 }

Example:以树形结构的形式输出指定目录下面的所有文件

 1 #include <unistd.h>
 2
 3 #include <stdio.h>
 4
 5 #include <dirent.h>
 6
 7 #include <string.h>
 8
 9 #include <sys/stat.h>
10
11 #include <stdlib.h>
12
13 void printdir(char *dir, int depth)//depth为缩进空格数
14
15 {
16
17     DIR *dp = opendir(dir);
18
19    if(NULL == dp)
20
21    {
22
23         fprintf(stderr,"cannot open directory: %s\n", dir);
24
25         return;
26
27     }
28
29   chdir(dir);
30
31     struct dirent *entry;
32
33     struct stat statbuf;
34
35 while((entry = readdir(dp)) != NULL)
36
37 {
38
39         stat(entry->d_name,&statbuf);
40
41         if(S_ISDIR(statbuf.st_mode)) //是目录
42
43 {
44
45             if(strcmp(".",entry->d_name) == 0 || strcmp("..",entry->d_name) == 0)
46
47                 continue;
48
49             printf("%*s%s/\n",depth,"",entry->d_name);
50
51             printdir(entry->d_name,depth+4);//递归
52
53         }
54
55         else //是文件
56
57     printf("%*s%s\n",depth,"",entry->d_name);
58
59     //printf(“%*s”,4,”*”); 该函数表示输出“___*”,前面输出3个空格。
60
61     //如果是printf(“%*s”,4,“**”);则表示输出“__**”,前面输出2个空格。
62
63     }
64
65     chdir("..");
66
67     closedir(dp);
68
69 }
70
71
72
73 int main(int argc, char* argv[])
74
75 {
76
77     char *topdir, pwd[2]=".";
78
79     if (argc < 2)
80
81         topdir=pwd;
82
83     else
84
85         topdir=argv[1];
86
87     printf("Directory scan of %s\n",topdir);
88
89     printdir(topdir,0);
90
91     printf("done.\n");
92
93     exit(0);
94
95 }

4标准输入/输出流

在进程一开始运行,就自动打开了三个对应设备的文件,它们是标准输入、输出、错误流,分别用全局文件指针stdin、stdout、stderr表示,stdin具有可读属性,缺省情况下是指从键盘的读取输入,stdout和stderr具有可写属性,缺省情况下是指向屏幕输出数据。

示例:

 1 #include <stdio.h>
 2
 3 #include <unistd.h>
 4
 5 int main()
 6
 7 {
 8
 9     char szBuf[32];
10
11     printf("Input string:");     //向屏幕输出一字符串
12
13     fgets(szBuf,sizeof(szBuf),stdin);//从键盘读入一行字符串
14
15     fprintf(stdout,"The string is:%s",szBuf);//向屏幕输出一行字符串
16
17     return 0;
18
19 }

时间: 2024-12-30 03:42:16

四、基于文件指针的文件操作的相关文章

文件描述符与文件指针等文件操作的几个问题

1.二者对比: 文件描述符就是open文件时产生的一个整数,直到一个索引作用,它用于UNIX系统中,用于标识文件.它是系统调用产生的. 文件指针是指向一个FILE的结构体,这个结构体里有一个元素就是文件描述符.它用于ANSI C标准的IO库调用中,用于标识文件.fopen是依赖于open的: 既然FILE中包含文件描述符元素,可以用fopen()直接获取指针fp,然后使用fp获得fp中所包含文件描述符fd的信息. 文件描述符应该是唯一的,但文件指针(值)却不是唯一的,但指向的对象却应该是唯一的.

通过文件指针插入文件内容

fseek(pf, -10, SEEK_END); 如果是这样的话,那么他所移动到的位置,右边有10个数字. 1.对文件基本操作 FILE *pf = fopen(path, "r+"); //文件指针在头部,不清空原来的内容. FILE *pf = fopen(path, "w+"); //文件指针在头部,会清空原来的内容. FILE *pf = fopen(path, "a+"); //尾部添加,文件指针会被移动到尾部. 2.文件指针不同操作

Linux下的文件操作——基于文件指针的文件操作(缓冲)

目录操作 创建和删除目录: 原型为: #include <sys/stat.h> #include <sys/types.h> #include <unistd.h> int mkdir(const char *pathname, mode_t mode); //创建目录,mode是目录权限 int rmdir(const char *pathname); //删除目录 获取目录信息: 原型为: #include <sys/types.h> #include

php开发之文件指针,文件锁定

(1) rewind() 函数 该函数将文件handle的指针设为文件流的开头,语法如下: bool rewind(resource handle) (2)fseek() 函数 fseek()函数实现文件指针的定位,语法如下: int fseek(resource handle,int offset[,int whence]) handle 参数为要打开的文件 offset为指针位置或者相对whence的参数的偏移量,可以是负值. whence 包括以下三种: a,SEEK_SET,位置等于of

Java--&gt;利用文件指针分割文件

--> 大体上和字节流分割的方式没什么区别,只是加入文件指针确定要开始分割的位置... package com.dragon.java.splitmp3; import java.io.File; import java.io.RandomAccessFile; import java.util.Scanner; public class Test { public static void main(String[] args) throws Exception { Scanner scanne

一起talk C栗子吧(第一百四十三回:C语言实例--文件操作:基于文件指针三)

各位看官们,大家好,上一回中咱们说的是基于文件指针进行文件操作的例子,这一回咱们继续说该例子.闲话休提,言归正转.让我们一起talk C栗子吧! 看官们,我们在上一回中详细地介绍了标准库中与文件操作相关的函数.不过,限于时间的原因,没有举具体的例子.还是那句老话,只说不练,不是我们的风格.因此,今天我们将通过具体的例子来说明如何使用文件指针来操作文件. 对文件的操作,还是使用我总结的文件操作三步曲比较好: p_file = fopen(file_name,"w"); //打开文件 re

Linu基础 文件IO(读写操作)

前言 本章讨论普通文件的读写.读写效率.简单介绍文件描述符.IO效率.文件共享和原子操作.dup.文件映射.临时文件. 文件描述符 在Linux系统中,打开的文件是用一个整数来表示的,表示打开文件的整数,称之为文件描述符.当需要往写数据/读数据时,读写函数都需要文件描述符作为参数,以便系统知道用户操作的时哪个文件. 文件基本操作 open/creat mode选项 解释 O_RDONLY 读方式打开 O_WRONLY 写方式打开 O_RDWR 读写方式打开 O_CREAT 创建文件,如果文件存在

php文件的处理和操作

好长时间没有看php手册了,有些关于文件操作方面的知识点发现从没有学过,现补习一下,顺便整理一下: 1.文件的打开:fopen()   此函数的第一个参数含有要打开的文件的名称,第二个参数规定了使用哪种模式来打开文件 r 打开文件为只读.文件指针在文件的开头开始. w 打开文件为只写.删除文件的内容或创建一个新的文件,如果它不存在.文件指针在文件的开头开始. a 打开文件为只写.文件中的现有数据会被保留.文件指针在文件结尾开始.创建新的文件,如果文件不存在. x 创建新文件为只写.返回 FALS

python 读写文件和设置文件的字符编码

一. python打开文件代码如下: f = open("d:\test.txt", "w") 说明:第一个参数是文件名称,包括路径:第二个参数是打开的模式mode ‘r’:只读(缺省.如果文件不存在,则抛出错误)‘w’:只写(如果文件不存在,则自动创建文件)‘a’:附加到文件末尾‘r+’:读写 如果需要以二进制方式打开文件,需要在mode后面加上字符”b”,比如”rb””wb”等 二.python读取文件内容f.read(size) 参数size表示读取的数量,可