【问题标题】:Unable to read file contents into buffer using read()无法使用 read() 将文件内容读入缓冲区
【发布时间】:2017-11-08 09:04:06
【问题描述】:

以下是在 Ubuntu OS 16.04 上使用 GNU 编译器(g++ 命令)编译的示例代码:

#include<iostream>
#include<unistd.h>
#include<fcntl.h>
#include <errno.h>
int main()
{           char* pBuffer;          

            char* storedfilepath = "/home/rtpl/Desktop/ts.mp4";

            std::cout<<"\n Opening file at "<<storedfilepath<<"\n";

            int NumBytesToRead = 1000 ;
            int filedes = open(storedfilepath,O_RDONLY);

            std::cout<<"\n value of error is "<<errno<<"\n";

            std::cout<<"\n value of filedes is "<<filedes;

            if (filedes==0)
            std::cout<<"\n File cannot be opened";
            else
            {
            std::cout<<"\n File opened successfully";
            std::cout<<"\n Now reading file\n"; 

            }

            //if(
            int ret = read(filedes,pBuffer,NumBytesToRead);

            std::cout<<"\n value of error is "<<errno<<"\n";

            if(ret!= -1)
            std::cout<<"\n File read successfully";
            else
            std::cout<<"\n File contents cannot be read";   

            std::cout<<"\nEnd.\n";  

            close(filedes);
            return 0;

} 

编译时;我收到这条消息:

rtpl@rtpl-desktop:~/Desktop$ g++ -g checkts.cpp
checkts.cpp: In function ‘int main()’:
checkts.cpp:8:27: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
    char* storedfilepath = "/home/rtpl/Desktop/ts.mp4";

执行时:

rtpl@rtpl-desktop:~/Desktop$ ./a.out

 Opening file at /home/rtpl/Desktop/ts.mp4

 value of error is 0

 value of filedes is 3
 File opened successfully
 Now reading file

 value of error is 14

 File contents cannot be read
End.

整个gdb调试可以在here找到。

问题:为什么文件合法且编译器不报错时,文件内容不被读取?

【问题讨论】:

  • 您有很多不同且不相关的问题。每个问题只能回答一个问题。
  • 哦,但我只有一个问题,为什么我无法打开文件
  • 使用std::string、std::vector、std::array、fstream而不是char指针并打开。
  • if (filedes==0) std::cout&lt;&lt;"\n File cannot be opened"; 是错误的。 open() 在失败时返回 -1,而不是零。 int ret = read(...); is also incorrect. read()` 返回 ssize_t 而不是 int - 虽然这可能不会对您的代码造成任何问题,但在某些情况下可能会导致问题。您可以使用perror( "read()" )errno 值转换为输出到stderr 的字符串。
  • @manni66 使用std::string、std::vector、std::array、fstream而不是char指针并打开。在所有这些代码层下,你做什么认为std::vectorstd::arrayfstream 用于将数据实际读入进程的地址空间?也许 OP 正在尝试了解事情的实际运作方式并想要使用read()

标签: c++ file fcntl unistd.h


【解决方案1】:

假设您运行的是 Linux,errno 的值 14 是 EFAULT,或“错误地址”。

给定代码

char* pBuffer;
  .
  .
  .
int ret = read(filedes,pBuffer,NumBytesToRead);

pBuffer 未初始化或未设置,因此pBuffer 中的值是不确定的,它肯定不指向有效地址。

您实际上需要提供一个缓冲区,read() 可以放置读取的数据:

char buffer[ 1024 ]
   .
   .
   .
ssize_t ret = read(filedes,buffer,NumBytesToRead);

可以工作,只要NumBytesToRead 不超过buffer 中的字节数。 另请注意,ret 现在是正确的ssize_t,而不是int

【讨论】:

    猜你喜欢
    • 2021-09-26
    • 2012-04-14
    • 2015-08-20
    • 2018-10-02
    • 2013-05-20
    • 1970-01-01
    • 1970-01-01
    • 2018-07-21
    • 2012-01-28
    相关资源
    最近更新 更多