linux中文件I/O操作(系统I/O)

我们都知道linux下所有设备都是以文件存在的,所以当我们需要用到这些设备的时候,首先就需要打开它们,下面我们来详细了解一下文件I/O操作。

用到的文件I/O有以下几个操作:打开文件、读文件、写文件、关闭文件等,对应用到的函数有:open、read、write、close、lseek(文件指针偏移)

文件描述符:对于内核而言,所有打开的文件都通过文件按描述符引用。文件描述符是一个非负整数。
                      当打开一个现有文件或者创建一个新文件时,内核向进程返回一个文件描述符。
                      当读、写一个文件时,使用open/creat返回的文件描述符标识该文件,将其作为参数传送给read或write。

linux系统下文件描述符0是标准输入,1是标准输出,2是标准出错,所以一般打开文件的时候文件描述符都是从3开始。

这里read和write是不能格式化读取和写入,如果想了解文件怎么格式化读取和写入的话,可以看看我以前写的一篇随笔。

一、打开文件
 (1)头文件
       #include <sys/types.h>
       #include <sys/stat.h>
       #include <fcntl.h>

 (2)函数原型    int open(const char *pathname, int flags);

      参数:
      a、pathname:打开或者创建的文件名字,如"text"

      b、 flags:
         O_RDONLY:只读打开
         O_WRONLY:只写打开
         O_RDWR:读、写打开
         O_CREAT:若此文件不存在则创建它,使用O_CREAT时后面要跟文件的访问权限位,如O_CREAT,0777
         O_APPEND:每次写时都追加到文件的尾端
         O_EXCL :如果同时指定了O_CREAT,而文件已经存在,则出错,用此可以测试一个文件是否
                  存在,如果不存在,则创建此文件,这使测试和创建两者成为一个原子操作
         O_DSYNC:使每次write等待物理I/O操作完成,但是如果该写操作并不影响读取刚写入的
                  数据,则不需等待文件属性被更新
         O_NONBLOCK :如果path引用的是一个FIFO、一个块特殊文件或一个字符特殊文件,则
                      此选项为文件的本次打开操作和后续的I/O操作设置非阻塞方式
         O_NOCTTY:如果path引用的是  终端设备,则将该设备分配为此进程的控制终端
         O_SYNC:使每次write要等待物理I/O操作完成,包括有该write引起的文件属性更新所需的I/O
         O_TRUNC:如果文件存在,并且是常规文件而且以读写或者只写打开,则将其长度截断为0,
                  如果文件是FIFO或终端设备文件,O_TRUNC标志被忽略,否则O_TRUNC不明确
         O_DIRECTORY:如果pathname引用的不是目录,则出错

(3)返回值:
     成功:文件描述符
     失败:-1     

二、读取文件
(1)头文件  #include <unistd.h>

(2)函数原型   ssize_t read(int fd, void *buf, size_t count);
     参数:
     a、fd:调用open后返回的文件描述符
     b、buf:用来存放从文件中读到的数据的缓冲区
     c、count:读取的字节数

(3)返回值:
     成功:读到的字节数,如果读到文件尾端,则返回0
     失败:-1

三、写数据
(1)头文件 #include <unistd.h>

(2)函数原型   ssize_t write(int fd, const void *buf, size_t count);
     参数:
     a、fd:调用open后返回的文件描述符
     b、buf:从来存放数据的缓冲区
     c、count:写入数据的字节数

(3)返回值:
     成功:返回已写的字节数
     失败:-1

四、关闭文件
(1)头文件  #include <unistd.h>

(2)函数原型  int close(int fd);
     参数:
     a、fd:调用open后返回的文件描述符

五、文件偏移
 (1)头文件  #include <sys/types.h>
              #include <unistd.h>

 (2)函数原型   off_t lseek(int fd, off_t offset, int whence);
      参数:
      a、fd:调用open后返回的文件描述符
      b、offset  和参数whence有关,通常设置为0 (according  to  thedirective whence as follows)
      c、whence:
         SEEK_SET: 将文件的偏移量设置为距文件开始处offset个字节
         SEEK_CUR:将文件的偏移量设置为其当前值加offset个字节,offset可为正或负
         SEEK_END: 将文件的偏移量设置为文件长度加offset,offset可为正或负

(3)返回值:
     成功:返回新的文件偏移量
     失败:-1

下面是代码:

#include <sys/types.h>
#include <sys/stat.h>
#include <sys/fcntl.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

#define PATHNAME "text.txt"
#define LENGTH 4096

void error(char *name) //错误提示
{
    perror(name);
    exit(1);
}

int main(int argc,char *argv[])
{

    int fd ; //存放文件描述符
    int size1; //读操作时的返回值
    int size; //写操作时的返回值
    int offset; //文件偏移量

    //打开文件
    /*O_REWR表示已读写权限打开文件,O_CREAT表示如果文件不存在则创建
    *创建的新文件的权限为0777,即是可读可写可执行,O_APPEND表示
    *写入数据时从文件尾端写入*/
    if((fd = open(PATHNAME,O_RDWR|O_CREAT|O_APPEND,0777)) == -1)
    {
        error("open");
    }        

    char buf[LENGTH];
    bzero(buf,sizeof(buf));

    //从文件中读取数据
    if((size1 = read(fd,buf,sizeof(buf))) == -1)
    {
        error("read");
    }

    printf("%s\n",buf);

   char buf1[LENGTH] = "小世界";
   //写入数据到文件中
   if((size = write(fd,buf1,sizeof(buf))) == -1)
   {
       error("write");
   }

    char buf3[LENGTH] = "hello world";
    if((size = write(fd,buf3,sizeof(buf3))) == -1)
    {
        error("write");
    }

    //因为写入数据到文件中的时候已经把文件指针偏移到文件尾端了,所以要重新把文件指针偏移到文件头,方便下面的读操作
    if((offset = lseek(fd,0,SEEK_SET)) == -1)
    {
        error("lseek");
    }

    bzero(buf,sizeof(buf));
    if((size1 = read(fd,buf,sizeof(buf))) == -1)
    {
        error("read");
    }
    printf("%s\n",buf);

    //关闭文件
    close(fd);
    return 0;
}

这是我在ubuntu上运行的结果,但是有个奇怪的地方就是我在Windows下打开文件的时候没有看到后面写进去的内容,而且出现乱码,在ubuntu下用cat命令却能看到文件中的全部内容,并且没有乱码

  • 用cat命令打开文件
  • 终端输出
  • windowns下打开
时间: 2024-11-05 17:20:29

linux中文件I/O操作(系统I/O)的相关文章

Linux中文件的基本属性

一.用户及用户组 所有者(属主):一般为文件的创建者,谁创建了该文件,就自然的成为该文件的所有者,每个文件的所有者(属主)有且仅有一个.用ll命令可以看到文件的所有者. 所属组(属组):当某个用户创建了一个文件后,这个文件的所在组就是该用户所在的组,一个用户可以属于多个组但仅有一个主组,用ll命令可以看到文件的所有组. 其他人:除开文件的所有者和所属组之外的用户,系统的其它用户都是文件的其他者.比如创建了两个用户Tom和Jerry,Tom相对Jerry创建的文件来说就是其他人. 二.文件权限 L

linux常用文件I/O操作之文件共享的实现方式

 1.文件共享的三种实现方式  1.什么是文件共享:    (1)文件共享就是同一个文件(同一个文件指的是同一个inode,同一个pathname)被多个独立的读写体(几乎可以理解为多个文件描述符)去同时(一个打开尚未关闭的同时另一个去操作)操作. (2)文件共享的意义有很多:譬如我们可以通过文件共享来实现多线程同时操作同一个大文件,以减少文件读写时间,提升效率.     2.文件共享的核心就是怎么弄出来多个文件描述符指向同一个文件.     3.常见的三种文件共享情况: 1.是同一个进程中多次

linux下文件的读写操作(openreadwrite)

linux下文件的读写操作(openreadwrite) 转 http://www.2cto.com/os/201403/285837.html open(打开文件) 相关函数 read,write,fcntl,close,link,stat,umask,unlink,fopen 表头文件 #include<sys/types.h>#include<sys/stat.h>#include<fcntl.h> 定义函数 int open( const char * path

Linux中文件描述符和打开文件之间的关系

Linux中文件描述符和打开文件之间的关系 文件描述符: 在形式上是一个非负整数.实际上,它是一个索引值,指向内核为每一个进程所维护的该进程打开文件的记录表. Linux中的文件类型 Linux系统中把一切都看做文件,包括普通文件-.目录文件d.字符设备文件c.块设备文件b.符号链接文件l.文件描述符是内核为了高效管理已被打开的文件所创建的索引(一个非负整数),用于指代已被打开的文件,Linux下所有的的I/O操作的系统调用都是通过文件描述符执行.例如0表示标准输入.1表示标准输出.3表示标准错

MD5的好处及linux中文件MD5校验和的应用

MD5算法简介: MD5全称是报文摘要算法(Message-Digest Algorithm5),此算法对任意长度的信息逐位进行计算,产生一个二进制长度为128位(十六进制长度就是32位)的"指纹"(或称"报文摘要"),不同的文件产生相同的报文摘要的可能性是非常非常之小的. Message Digest Algorithm MD5为计算机安全领域广泛使用的一种散列函数,MD5算法常常被用来验证网络文件传输的完整性,防止文件被人篡改.它是用复杂的数学算法求得的一个12

(六)kernel中文件的读写操作可以使用vfs_read()和vfs_write

需要在Linux kernel--大多是在需要调试的驱动程序--中读写文件数据.在kernel中操作文件没有标准库可用,需要利用kernel的一些函数,这些函数主要有: filp_open() filp_close(), vfs_read() vfs_write(),set_fs(),get_fs()等,这些函数在linux/fs.h和asm/uaccess.h头文件中声明.下面介绍主要步骤 1. 打开文件 filp_open()在kernel中可以打开文件,其原形如下: strcut file

linux中文件的三种时间

Linux 中文件的三种时间 文件的三种时间: 1.        mtime 文件的修改时间 文件的内容发生改变.包括文件中空格数目.字符的变动再复原等这些看上去并不影响有效数据内容的操作. 有意的改变时间戳.Eg:使用touch –m –t 2016666666666fileName这样的命令故意改变mtime. 2.        ctime 文件的改变时间 文件的"属性"改变.Eg:文件的权限.属主.属组等. mtime发生改变和人为的改变atime的情况,Eg:touch –

linux 中文件类型和颜色的区分

linux 中文件类型和颜色的区分 to be  continued linux 中文件类型和颜色的区分,布布扣,bubuko.com

linux中文件和文件夹的操作

一.文件操作 1.创建( > touch ) > 2.txt 在当前路径创建文件2.txt,(如果2.txt本来就存在,2.txt的内容会被清除) touch 3.log 在当前路径创建文件3.log 2.删除( rm ) rm: -i 删除前逐一询问确认. -f 即使原档案属性设为唯读,亦直接删除,无需逐一确认. -r 将目录及以下之档案亦逐一删除.需要提醒的是:使用这个rm -rf的时候一定要格外小心,linux没有回收站的 rm  2.txt 删除当前路径中的文件2.txt,需确认. r