IO(Linux)(C)

13 篇文章 0 订阅
  • 缓冲:

setvbuf

#include <stdio.h>

int setvbuf(FILE *stream, char *buf, int mode, size_t size);

功能:更改缓冲区类型

返回值:0成功,非0失败

stream:流(输入流、输出流)

buf:指定缓冲区地址(默认为NULL)

mode:缓冲模式(全缓冲4096字节、行缓冲1024字节、无缓冲)_IOFBF、_IOLBF、_IONBF

size:缓冲区大小

fflush

#include <stdio.h>

int fflush(FILE *fp);

强制刷新一个流(清空)

标准流:

文件IO(int) 标准IO(FILE*)

标准输入: 0 stdin

标准输出: 1 stdout

标准出错: 2 stderr

  • 标准IO库:

fopen

#include <stdio.h>

FILE *fopen(const char *pathname, const char *mode);

功能:内核打开一个文件,并以流的形式来标记

返回值:成功返回流指针,失败返回NULL

pathname:文件路径名

mode:打开方式

r 只读

r+ 读写

w 写(有内容会覆盖)(打开时就清空)

w+ 读写(不存在会创建,写入有内容会覆盖)(打开时就清空)

a 追加

a+ 追加读

b:以二进制的方式打开

freopen

FILE *freopen(const char *pathname, const char *mode, FILE *stream);

功能:修改当前的流(将老的流修改为新的流)(重定向)

pathname:新的文件路径名

mode:打开方式

stream:已经存在的流

fclose

#include <stdio.h>

int fclose(FILE *stream);

功能:通过流指针关闭打开的文件

返回值:成功为0,失败为EOF(实则为-1)

stream:已经打开的流指针

读:

#include <stdio.h>

int fgetc(FILE *stream);

功能:从流中读取一个字符

返回值:成功返回一个ASCII码(int),失败为EOF

stream:已经打开的流指针

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

功能:从流中读取一个字符串(一行一行读,行末尾会自动添加'\n',字符串末尾添加'\0')

(当预计读的个数比实际字节个数多一个,只会有'\0')

(当预计读的个数比实际字节个数多两个,先有'\n',再有'\0')

(最短为2,为1时只有'\0')

返回值:成功返回字符指针(字符串),失败为NULL

s:用来存储字符串

size:字符串长度

stream:已经打开的流指针

#include <string.h>

void *memset(void *s, int c, size_t n);

memset(arr,0,sizeof(arr));//清空字符串

写:

#include <stdio.h>

int fputc(int c, FILE *stream);

功能:向流中输出一个字符

返回值:成功返回ASCII码,失败为EOF

c:字符ASCII码

stream:已经打开的流指针

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

功能:向流中输出一个字符串(按行写)

返回值:成功返回1,失败为EOF

s:输出的字符串

stream:已经打开的流指针

int fprintf(FILE *stream, const char *format, ...);//其后的参数与printf一致

功能:向流中输出内容,将数据转为字符写入

返回值:成功返回打印的字符的个数,失败为负

stream:要写的流

format:字符指针

int sprintf(char *str, const char *format, ...);//其后的参数与printf一致

功能:向缓冲区中输出内容,将数据转为字符写入

返回值:成功返回打印的字符的个数,失败为负

str:缓冲区地址

format:字符指针

按对象读写:

读:

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

功能:从流中读取内容,按对象读

返回值:成功返回实际读到的对象个数,失败返回非正数

ptr:缓冲区地址(存放读入内容的地址)

size:每个对象有几个字节

nmemb:预计要读多少个对象

stream:要读的流

写:

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

功能:向流中输出内容,按对象写(一个字节一个字节写入)

返回值:成功返回实际输出的对象个数,失败返回非正数

ptr:缓冲区地址(存放输出内容的地址)

size:每个对象有几个字节

nmemb:预计要写多少个对象

stream:要写的流

报告文件内光标位置:

long ftell(FILE *stream);//返回当前光标位置

文件偏移:

int fseek(FILE *stream, long offset, int whence);

功能:光标移动

返回值:成功返回0,失败为-1

offset:偏移量

whence:基础位置(SEEK_SET 头, SEEK_CUR 当前位置, SEEK_END 尾)

  • 文件IO:

直接的系统调用

open/close/read/write/lseek

#include <fcntl.h>

int open(const char *pathname, int flags, mode_t mode);

功能:站在内核的角度打开一个文件,并产生一个文件描述符

(文件描述符:内核用于标记已打开的文件的数字,类似与流,其值为最小的非负整数)

0-->标准输入

1-->标准输出

2-->标准出错

pathname:文件路径

flags:打开方式或权限(可以多选必须包括前三O_RDONLY 只读, O_WRONLY 只写, O_RDWR 读写, O_CREAT 不存在则创建,O_TRUNC 覆盖)

mode:创建时的权限( 当选择O_CREAT时需要填写)(如0777,使用这个权限 与上 umask取反 才是实际的权限)(先对umask取反再与)

#include <unistd.h>

ssize_t read(int fd, void *buf, size_t count);

功能:从打开的文件描述符中读取内容

返回值:成功返回读到的字节数,失败为-1

fd:文件描述符

buf:存放读取的内容

count:预计读到的字节(不能超过buf的大小)

ssize_t write(int fd, void *buf, size_t count);

功能:往打开的文件描述符中写内容

返回值:成功返回写入的字节数,失败为-1

fd:文件描述符

buf:存放将要写入的内容

count:预计写到的字节(不能超过buf的大小)

int close(int fd);

功能:关闭已经打开的文件描述符

返回值:成功返回0,失败为-1

fd:文件描述符

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

功能:光标移动

返回值:成功返回非负整数,失败为-1

fd:文件描述符

offset:偏移量

whence:基础位置(SEEK_SET 头, SEEK_CUR 当前位置, SEEK_END 尾)

#include <dirent.h>

DIR *opendir(const char *name);

功能:打开一个目录文件,并产生一个专用于目录的流

返回值:成功返回目录指针,失败为NULL

name:目录路径

struct dirent *readdir(DIR *dirp);

功能:读一次目录流,得到一个文件的信息

返回值:成功一个dirent结构体指针类型,失败为NULL

dirp:已经打开的目录流

  • 动态库和静态库的分析(默认动态库)

  • 静态库:包含所有文件(加密后的二进制文件)

gcc -c hello.c -o hello.o//生成二进制文件

ar crs libmyhello.a hello.o//将二进制文件转为静态库

gcc main.c -L. -lmyhello(-L库的路径,-l库的名字,要去掉lib与.a)//编译(若动态库静态库重名-static改为静态库)

-I(i) :指定头文件的路径

-L:指定库文件的路径

-l:链接某个具体的库(库名字)

  • 动态库:在运行时才链接相关文件(要有相应环境)

gcc -fPIC -Wall -c test.c(-fPIC创建与地址无关的编译程序)//使二进制与地址无关,方便链接库时直接插入

gcc -shared -o libmytest.so test.o//创建动态库

gcc main.c -L. -lmytest//编译

//需要系统能够在运行程序的时候找到动态库

可以把动态库文件放在/lib或者/usr/lib/目录下,这样可以直接找到。

也可以创建一个临时的文件:/etc/ld.so.conf.d/my.conf 在这个文件中写上动态库的路径

保存后ldconfig刷新库的环境变

  • 补充:

#include <sys/types.h>

#include <sys/stat.h>

#include <unistd.h>

int stat(const char *pathname, struct stat *statbuf);//若路径为一个链接文件,实际上是返回被链接文件的信息

int fstat(int fd, struct stat *statbuf);//文件描述符

int lstat(const char *pathname, struct stat *statbuf);//若路径为一个链接文件,返回链接文件的自身的信息

功能:获取文件信息

返回值:成功0,失败-1

struct stat {

dev_t st_dev; /* ID of device containing file */

ino_t st_ino; /* Inode number */

mode_t st_mode; /* File type and mode */

nlink_t st_nlink; /* Number of hard links */

uid_t st_uid; /* User ID of owner */

gid_t st_gid; /* Group ID of owner */

dev_t st_rdev; /* Device ID (if special file) */

off_t st_size; /* Total size, in bytes */

blksize_t st_blksize; /* Block size for filesystem I/O */

blkcnt_t st_blocks; /* Number of 512B blocks allocated */

/* Since Linux 2.6, the kernel supports nanosecond

precision for the following timestamp fields.

For the details before Linux 2.6, see NOTES. */

struct timespec st_atim; /* Time of last access */

struct timespec st_mtim; /* Time of last modification */

struct timespec st_ctim; /* Time of last status change */

#define st_atime st_atim.tv_sec /* Backward compatibility */

#define st_mtime st_mtim.tv_sec

#define st_ctime st_ctim.tv_sec

};

部分代码示例

  • 标准IO

//fopen
#include <stdio.h>
int main()
{
    FILE *fp=fopen("text01.txt","w+");
    if(fp==NULL)
    {   
        perror("text01.txt");
        return -1; 
    }   
}
//fgetc fputc 拷贝文件
#include <stdio.h>
int main(int argc, char *argv[])
{  
    if(argc<3)
    {
        printf("%s src_file dest_file",argv[0]);
        return -1;
    }
    FILE *fp01 = fopen(argv[1],"r");
    if(fp01==NULL)
    {
        perror("src_file");
        return -1;
    }
    FILE *fp02 = fopen(argv[2],"w");
    if(fp02==NULL)
    {
        perror("dest_file");
        return -1;
    }
    char ch;
    while(1)
    {
        ch=fgetc(fp01);
        if(ch==EOF)
        {
            break;
        }
        fputc(ch,fp02);
    }
    return 0;
    fclose(fp01);
    fclose(fp02);
} 
//fread fwrite 拷贝文件
#include <stdio.h>
int main(int argc, char *argv[])
{ 
    if(argc<3)
    {
        printf("%s file_src file_dest\n",argv[0]);
        return -1;
    }
    FILE *fp_src = fopen(argv[1],"r");
    if(fp_src==NULL)
    {
        perror("fp_src");
        return -1;
    }
    FILE *fp_dest = fopen(argv[2],"w");
    if(fp_dest==NULL)
    {
        perror("fp_dest");
        return -1;
    }
    int ret = -1;
    int arr[50];
    while(1)
    {
        ret = fread(arr,1,sizeof(arr),fp_src);
        if(ret<=0)
        {
            perror("fread");
            break;
        }
        fwrite(arr,1,ret,fp_dest);
    } 
    
    return 0;
} 
  • 文件IO

//open read write 拷贝文件
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>

int main(int argc, char *argv[])
{ 
    int fd01 = open(argv[1],O_RDONLY);
    int fd02 = open(argv[2],O_WRONLY);
    char buf[50];
    int ret;
    while(1)
    {
        ret = read(fd01,buf,sizeof(buf));
        if(ret<=0)
        {
            break;
        }
        write(fd02,buf,ret);
    }
    return 0;
} 
//lseek 在当前光标位置写入(覆盖)
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
int main(int argc, char *argv[])
{ 
    int fd = open(argv[1],O_RDWR);
    char buf[10];
    read(fd,buf,10);
    lseek(fd,0,SEEK_CUR);
    write(fd,"start_insert:",14);
    write(fd,buf,10);
    return 0;
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值