Linux应用编程学习记录(二)

        今天来继续学习文件操作的相关API。早上查了下资料,发现现在学的这些API隶属于POSIX标准,POSIX翻译过来就是可移植操作系统接口,在UNIX类系统中应用的十分广泛。处理文件的API还有很多别的标准,比如ANSI C标准,它应该是标准C语言提供的库函数。在别人的文章中看到,这二者比较起来的话,POSIX应该是更底层的代码,而ANSI C是较为上层的代码。换言之,你在Linux中使用后者的某个函数来操作文件,极有可能就是间接或者直接调用了前者中的对应函数。

1.    read函数

        这个函数与write函数的功能正好相反,各参数的功能也可以类比来记忆:

A)返回值是有符号整型,代表实际读取到了几个字符

B)第一个参数是目标文件的句柄

C)第二个参数是未指定类型的指针,其实就是某个缓冲区域的首地址,将来用来存放读取的数据

D)第三个参数是希望读取的字节数

2.    read函数使用体验

A)与write函数类似,read函数也存在对同一个文件多次读取的情况。经过测试,确实还是像前者一样,一旦打开了一个文件。只要不关闭它,并且使用相同的文件句柄,本次读取就会在上一次末尾的地方自动接续。

B)确实像教材中说的那样,如果文本中有6个字符,而你却一次性要求读取10个,那么返回值会告诉你,只能读出6个。

C)如果经过上次读取操作,已经读完了文本中的内容,你却还要继续读取,那么返回值会告诉你,已经见底了。

D)在测试中发现一个有趣的现象,用write函数手写的文件,和自己用vi编辑器手写的文件有区别。同样都是输入abcdef这6个字符,用write函数写入什么就是什么;用vi编辑器写入,看起来好像也只有这6个字符。再用read函数去读取并且用printf函数打印出来的时候就能看到,后者还多了个空格:

注:上图中printf函数通过参数配置为右对齐显示10个字符。

3.  贴上这部分的测试代码

#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <stdio.h>        //为了能运行printf函数所添加的头文件

int main(int argc, char* argv[])
{
    int fd1=-1;
    int fd2=-1;
    int res=0;
    char buf1[10];
    char buf2[10];
    char buf3[10];

/************************打开文件file1,获取句柄****************************/
    fd1 = open("file1.txt", O_RDWR);
    if (fd1 < 0)
        printf("open file1 failed!\n");
    else
        {
        printf("open file1 success!\n");
        printf("file1 's fd is %d\n",fd1);
        }
/******************从文件file1读取数据到buf1*******************/
    res = read(fd1, buf1, 10);
    if (res == 0)
        printf("read file1 to the end!\n");
    else if (res <= -1)
        printf("read file1 failed!\n");
    else
        {
        printf("read %d bytes form file1 !\n",res);
        printf("%10s\n\n",buf1);
        }

/************************打开文件file2,获取句柄****************************/
    fd2 = open("file2.txt", O_RDWR);
    if (fd2 < 0)
        printf("open file2 failed!\n");
    else
        {
        printf("open file2 success!\n");
        printf("file2 's fd is %d\n",fd2);
        }
/******************从文件file2读取数据到buf2*******************/
    res = read(fd2, buf2, 10);
    if (res == 0)
        printf("read file2 to the end!\n");
    else if (res <= -1)
        printf("read file2 failed!\n");
    else
        {
        printf("read %d bytes form file2 !\n",res);
        printf("%10s\n",buf2);
        }

    close(fd1);
    close(fd2);
    return 0;
}

4.  close函数

        这个函数与open相对应,用法十分简单。

A)返回值是有符号整型数据,只有两种可能:0代表正常关闭,-1代表失败

B)只有一个参数,文件句柄

5.  一些有意思的细节

        当我们对文件进行读操作的时候,往往一次不会全部读出来。比如一个文件中有10个字符,我一次只读5个字符。完事以后还想把它打印出来显示一下。我采用的方法是:

printf("They are %5s",buf);

这种方法指定打印缓冲区5个字符,并且右对齐。我在教材上看到另一种做法:

res = read(fd, buf, 5);

buf[res]='\0';

在read之后,立即给buf手动加上一个字符串结束标志的'\0',这样再用printf的时候就不用指定显示几个字符了。碰到字符串结束标志的时候,printf知道见好就收~

这种方法的好处在于,有时候你根本不知道能读出几个字符,,这时候还怎么指定?另外,而res能够忠实的反馈到底读出来几个字符。因此buf[res]='\0';  这种方法能保证'\0'正好加在最后一个有效字符的后面。

猜你喜欢

转载自blog.csdn.net/K23428/article/details/81974318