lseek() 后跟 new open() 返回 0

Posted

技术标签:

【中文标题】lseek() 后跟 new open() 返回 0【英文标题】:lseek() returning 0 when followed by new open() 【发布时间】:2010-01-10 19:15:49 【问题描述】:

我有以下代码(它是“示例”代码,所以没什么花哨的):

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

int main()

    char buffer[9];
    int fp = open("test.txt", O_RDONLY);

    if (fp != -1) // If file opened successfully
    
        off_t offset = lseek(fp, 2, SEEK_SET); // Seek from start of file
        ssize_t count = read(fp, buffer, strlen(buffer));
        if (count > 0) // No errors (-1) and at least one byte (not 0) was read
        
            printf("Read test.txt %d characters from start: %s\n", offset, buffer);
        

        close(fp);
    

    int fp2 = open("test.txt", O_WRONLY);
    if (fp2 != -1)
    
        off_t offset = lseek(fp2, 2, SEEK_CUR); // Seek fraom current position (0) - same result as above in this case
        ssize_t count = write(fp2, buffer, strlen(buffer));
        if (count == strlen(buffer)) // We successfully wrote all the bytes
        
             printf("Wrote to test.txt %d characters from current (0): %s\n", offset, buffer);
        

        close(fp2);
    

此代码不会按原样返回第一个打印输出(读取),第二个打印输出显示:“Wrote test.txt 0 characters from current (0):”表示它没有在文件中的任何位置查找,并且缓冲区为空。

奇怪的是,如果我注释掉 fp2 = open("test.txt", O_WRONLY); 中的所有内容,第一个打印输出会返回我预期的结果。一旦我包含第二个open 语句(即使没有别的),它就不会写它。它是否会以某种方式重新排序开放语句或其他内容?

【问题讨论】:

它当然不会重新排序调用打开。 【参考方案1】:

线

ssize_t count = read(fp, buffer, strlen(buffer));

错了,您正在使用未初始化缓冲区的 strlen 。您可能希望缓冲区的大小如下:

ssize_t count = read(fp, buffer, sizeof buffer);

当你将它打印为一个时,你应该确保缓冲区确实包含一个以 nul 结尾的字符串。

if (fp != -1) // If file opened successfully


    off_t offset = lseek(fp, 2, SEEK_SET); // Seek from start of file
    ssize_t count = read(fp, buffer, sizeof buffer - 1);
    if (count > 0) // No errors (-1) and at least one byte (not 0) was read
     
       buffer[count] = 0;

【讨论】:

似乎工作正常。似乎在程序的某些实例中,缓冲区在启动时会被垃圾填充,使其工作,有时它不是(在这种特殊情况下)。我和记忆... buffer 是一个自动变量,没有初始化为0,所以它包含随机值。如果bufferstatic 或“全局”,它将被初始化为所有字节0。【参考方案2】:

您确定每次运行时都会清除文件吗?

如前所述,第一次运行时,您只会看到第二个打印输出,而第二次您可能会看到第一个。

【讨论】:

以上是关于lseek() 后跟 new open() 返回 0的主要内容,如果未能解决你的问题,请参考以下文章

Unix系统编程()open,read,write和lseek的综合练习

lseek

文件IO详解---lseek函数详解

文件IO

使用 lseek 在 C 中获取文件的大小? [关闭]

JavaScript之函数