代码之家  ›  专栏  ›  技术社区  ›  BullyWiiPlaza

无法从Boost::mapped_文件读取:数据缓冲区为空

  •  0
  • BullyWiiPlaza  · 技术社区  · 6 年前

    我试图从一个映射文件中分块读取数据(因此 buffer_size file_offset 参数),但缓冲区总是 NULL . 文件已成功打开。我的代码如下:

    #include <boost/iostreams/device/mapped_file.hpp>
    #include <iostream>
    #include <boost/filesystem.hpp>
    
    namespace filesystem = boost::filesystem;
    
    using std::ios;
    using std::ifstream;
    
    char *read_mapped_bytes(const char *file_path, boost::iostreams::mapped_file mapped_file,
                            unsigned long long int buffer_size, unsigned long long int file_offset) {
        const filesystem::path memory_dump_file{file_path};
        mapped_file.open(memory_dump_file, boost::iostreams::mapped_file::readonly, buffer_size,
                         static_cast<boost::iostreams::stream_offset>(file_offset));
        if (mapped_file.is_open()) {
            auto read_buffer = mapped_file.data();
            if (read_buffer == nullptr) {
                printf("The mapped file buffer was NULL");
                exit(-1);
            }
            return read_buffer;
        } else {
            printf("Failed to open mapped file");
            exit(-1);
        }
    }
    
    int main(int argc, char *argv[]) {
        boost::iostreams::mapped_file mapped_file;
        auto buffer = read_mapped_bytes((const char *) "/mnt/d/Cpp/MyProject/myFile.bin", mapped_file,
                                        (unsigned long long int) 1000, (unsigned long long int) 0);
    
        exit(EXIT_SUCCESS);
    }
    

    请注意,文件路径是正确的,否则会导致异常:

    terminate called after throwing an instance of 'boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<std::ios_base::failure[abi:cxx11]> >'
      what():  failed opening file: No such file or directory: iostream error
    

    代码已在上运行 Ubuntu 18.04.01 LTS 使用 WSL Windows Subsystem for Linux ).

    strace ( strace -ff -o test.txt ./BoostTesting )代码执行的步骤如下所示:

    execve("./BoostTesting", ["./BoostTesting"], 0x7fffc2c75168 /* 17 vars */) = 0
    brk(NULL)                               = 0x7fffc5980000
    access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
    access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
    openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
    fstat(3, {st_mode=S_IFREG|0644, st_size=48784, ...}) = 0
    mmap(NULL, 48784, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f4759dab000
    close(3)                                = 0
    access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
    openat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/libboost_iostreams.so.1.65.1", O_RDONLY|O_CLOEXEC) = 3
    read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\200\300\0\0\0\0\0\0"..., 832) = 832
    fstat(3, {st_mode=S_IFREG|0644, st_size=105032, ...}) = 0
    mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f4759da0000
    mmap(NULL, 2200080, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f47597e0000
    mprotect(0x7f47597f8000, 2097152, PROT_NONE) = 0
    mmap(0x7f47599f8000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x18000) = 0x7f47599f8000
    close(3)                                = 0
    access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
    openat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/libboost_system.so.1.65.1", O_RDONLY|O_CLOEXEC) = 3
    read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0000\30\0\0\0\0\0\0"..., 832) = 832
    fstat(3, {st_mode=S_IFREG|0644, st_size=18544, ...}) = 0
    mmap(NULL, 2113856, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f47595d0000
    mprotect(0x7f47595d4000, 2093056, PROT_NONE) = 0
    mmap(0x7f47597d3000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x3000) = 0x7f47597d3000
    close(3)                                = 0
    access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
    openat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/libstdc++.so.6", O_RDONLY|O_CLOEXEC) = 3
    read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\360\303\10\0\0\0\0\0"..., 832) = 832
    fstat(3, {st_mode=S_IFREG|0644, st_size=1594832, ...}) = 0
    mmap(NULL, 3702816, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f4759240000
    mprotect(0x7f47593b9000, 2097152, PROT_NONE) = 0
    mmap(0x7f47595b9000, 49152, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x179000) = 0x7f47595b9000
    mmap(0x7f47595c5000, 12320, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f47595c5000
    close(3)                                = 0
    access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
    openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libgcc_s.so.1", O_RDONLY|O_CLOEXEC) = 3
    read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\300*\0\0\0\0\0\0"..., 832) = 832
    fstat(3, {st_mode=S_IFREG|0644, st_size=96616, ...}) = 0
    mmap(NULL, 2192432, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f4759020000
    mprotect(0x7f4759037000, 2093056, PROT_NONE) = 0
    mmap(0x7f4759236000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x16000) = 0x7f4759236000
    close(3)                                = 0
    access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
    openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
    read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\260\34\2\0\0\0\0\0"..., 832) = 832
    fstat(3, {st_mode=S_IFREG|0755, st_size=2030544, ...}) = 0
    mmap(NULL, 4131552, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f4758c20000
    mprotect(0x7f4758e07000, 2097152, PROT_NONE) = 0
    mmap(0x7f4759007000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1e7000) = 0x7f4759007000
    mmap(0x7f475900d000, 15072, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f475900d000
    close(3)                                = 0
    access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
    openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libz.so.1", O_RDONLY|O_CLOEXEC) = 3
    read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\220\37\0\0\0\0\0\0"..., 832) = 832
    fstat(3, {st_mode=S_IFREG|0644, st_size=116960, ...}) = 0
    mmap(NULL, 2212016, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f4758a00000
    mprotect(0x7f4758a1c000, 2093056, PROT_NONE) = 0
    mmap(0x7f4758c1b000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1b000) = 0x7f4758c1b000
    close(3)                                = 0
    access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
    openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libbz2.so.1.0", O_RDONLY|O_CLOEXEC) = 3
    read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0`\23\0\0\0\0\0\0"..., 832) = 832
    fstat(3, {st_mode=S_IFREG|0644, st_size=66800, ...}) = 0
    mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f4759d90000
    mmap(NULL, 2161864, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f47587f0000
    mprotect(0x7f47587ff000, 2093056, PROT_NONE) = 0
    mmap(0x7f47589fe000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0xe000) = 0x7f47589fe000
    close(3)                                = 0
    access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
    openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libpthread.so.0", O_RDONLY|O_CLOEXEC) = 3
    read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0000b\0\0\0\0\0\0"..., 832) = 832
    fstat(3, {st_mode=S_IFREG|0755, st_size=144976, ...}) = 0
    mmap(NULL, 2221184, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f47585d0000
    mprotect(0x7f47585ea000, 2093056, PROT_NONE) = 0
    mmap(0x7f47587e9000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x19000) = 0x7f47587e9000
    mmap(0x7f47587eb000, 13440, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f47587eb000
    close(3)                                = 0
    access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
    openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libm.so.6", O_RDONLY|O_CLOEXEC) = 3
    read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\200\272\0\0\0\0\0\0"..., 832) = 832
    fstat(3, {st_mode=S_IFREG|0644, st_size=1700792, ...}) = 0
    mmap(NULL, 3789144, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f4758230000
    mprotect(0x7f47583cd000, 2093056, PROT_NONE) = 0
    mmap(0x7f47585cc000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x19c000) = 0x7f47585cc000
    close(3)                                = 0
    mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f4759d80000
    arch_prctl(ARCH_SET_FS, 0x7f4759d811c0) = 0
    mprotect(0x7f4759007000, 16384, PROT_READ) = 0
    mprotect(0x7f47585cc000, 4096, PROT_READ) = 0
    mprotect(0x7f47587e9000, 4096, PROT_READ) = 0
    mprotect(0x7f47589fe000, 4096, PROT_READ) = 0
    mprotect(0x7f4758c1b000, 4096, PROT_READ) = 0
    mprotect(0x7f4759236000, 4096, PROT_READ) = 0
    mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f4759d70000
    mprotect(0x7f47595b9000, 40960, PROT_READ) = 0
    mprotect(0x7f47597d3000, 4096, PROT_READ) = 0
    mprotect(0x7f47599f8000, 4096, PROT_READ) = 0
    mprotect(0x7f475a008000, 4096, PROT_READ) = 0
    mprotect(0x7f4759c27000, 4096, PROT_READ) = 0
    munmap(0x7f4759dab000, 48784)           = 0
    set_tid_address(0x7f4759d81490)         = 1491
    set_robust_list(0x7f4759d814a0, 24)     = 0
    rt_sigaction(SIGRTMIN, {sa_handler=0x7f47585d5cb0, sa_mask=[], sa_flags=SA_RESTORER|SA_SIGINFO, sa_restorer=0x7f47585e2890}, NULL, 8) = 0
    rt_sigaction(SIGRT_1, {sa_handler=0x7f47585d5d50, sa_mask=[], sa_flags=SA_RESTORER|SA_RESTART|SA_SIGINFO, sa_restorer=0x7f47585e2890}, NULL, 8) = 0
    rt_sigprocmask(SIG_UNBLOCK, [RTMIN RT_1], NULL, 8) = 0
    prlimit64(0, RLIMIT_STACK, NULL, {rlim_cur=8192*1024, rlim_max=8192*1024}) = 0
    brk(NULL)                               = 0x7fffc5980000
    brk(0x7fffc59a1000)                     = 0x7fffc59a1000
    futex(0x7f47595c607c, FUTEX_WAKE_PRIVATE, 2147483647) = 0
    futex(0x7f47595c6088, FUTEX_WAKE_PRIVATE, 2147483647) = 0
    openat(AT_FDCWD, "/mnt/d/Cpp/MyProject/myFile.bin", O_RDONLY) = 3
    mmap(NULL, 1000, PROT_READ, MAP_SHARED, 3, 0) = 0x7f4759db6000
    fstat(1, {st_mode=S_IFCHR|0660, st_rdev=makedev(4, 1), ...}) = 0
    ioctl(1, TCGETS, {B38400 opost isig icanon echo ...}) = 0
    write(1, "The mapped file buffer was NULL", 31) = 31
    exit_group(-1)                          = ?
    +++ exited with 255 +++
    

    请注意,在为 Windows 同样的问题也出现了,所以很可能是我的代码或代码中的错误 Boost .

    1 回复  |  直到 6 年前
        1
  •  0
  •   BullyWiiPlaza    6 年前

    结果是我传递了错误的参数。此外,偏移量必须是 page size . 下面是独立于平台的示例源代码,演示了使用 mapped_file :

    #include <boost/iostreams/device/mapped_file.hpp>
    #include <iostream>
    #include <boost/filesystem.hpp>
    
    #ifdef _WIN32
    
    #include <sysinfoapi.h>
    
    #endif
    
    namespace filesystem = boost::filesystem;
    namespace io_streams = boost::iostreams;
    
    using std::ios;
    using std::ifstream;
    
    unsigned long long int get_page_size() {
    #ifdef _WIN32
        SYSTEM_INFO sysInfo;
        GetSystemInfo(&sysInfo);
        return (unsigned long long int) sysInfo.dwPageSize;
    #else
        return (unsigned long long int) sysconf(_SC_PAGE_SIZE);
    #endif
    }
    
    unsigned long long int get_file_size(const char *file_path) {
        filesystem::path file{file_path};
        auto generic_path = file.generic_path();
        return filesystem::file_size(generic_path);
    }
    
    std::vector<char> read_bytes(const char *file_path,
                                 unsigned long long int offset,
                                 unsigned long long int length) {
        io_streams::mapped_file_params parameters;
        parameters.path = file_path;
        parameters.length = static_cast<size_t>(length);
        parameters.flags = io_streams::mapped_file::mapmode::readonly;
        parameters.offset = static_cast<boost::iostreams::stream_offset>(offset);
    
        boost::iostreams::mapped_file_source file;
    
        file.open(parameters);
    
        if (file.is_open()) {
            auto buffer = file.data();
            std::vector<char> vector_buffer;
            for (auto buffer_index = 0; buffer_index < length; buffer_index++) {
                auto byte = buffer[buffer_index];
                vector_buffer.push_back(byte);
            }
    
            return vector_buffer;
        } else {
            printf("Failed to open file\n");
            exit(EXIT_FAILURE);
        }
    }
    
    int main(int argc, char *argv[]) {
    #ifdef _WIN32
        auto file_path = (const char *) R"(D:\Cpp\BoostTesting\test.bin)";
    #else
        auto file_path = (const char *) "/mnt/d/Cpp/BoostTesting/test.bin";
    #endif
    
        unsigned long long int offset = 0;
        unsigned long long int page_size = get_page_size();
        auto buffer_size = page_size;
        auto total_length = get_file_size(file_path);
    
        while (offset < total_length) {
            auto remaining_bytes = total_length - offset;
            if (buffer_size > remaining_bytes) {
                buffer_size = remaining_bytes;
            }
    
            auto buffer = read_bytes(file_path, offset, buffer_size);
            for (auto byte : buffer) {
                printf("%i ", byte);
            }
    
            offset += buffer_size;
        }
    
        return EXIT_SUCCESS;
    }