2015-02-14 18 views
11

Tôi đang cố gắng tạo một tệp ánh xạ bộ nhớ bằng cách sử dụng std::os::MemoryMap. Cách tiếp cận hiện tại trông như sau:Làm cách nào để tạo và ghi vào các tệp ánh xạ bộ nhớ?

use std::os; 
use std::ptr; 
use std::old_io as io; 
use std::os::unix::prelude::AsRawFd; 
use std::os::MapOption; 

let path = Path::new("test.mmap"); 

let f = match io::File::open_mode(&path, io::Open, io::ReadWrite) { 
    Ok(f) => f, 
    Err(err) => panic!("Could not open file: {}", err), 
}; 

let mmap_opts = &[ 
    MapOption::MapReadable, 
    MapOption::MapWritable, 
    MapOption::MapFd(f.as_raw_fd()) 
]; 

let mmap = match os::MemoryMap::new(1024*1024, mmap_opts) { 
    Ok(mmap) => { 
     println!("Successfully created the mmap: {}", mmap.len()); 
     mmap 
    } 
    Err(err) => panic!("Could not read the mmap: {}", err), 
}; 

unsafe { 
    let data = mmap.data(); 

    if data.is_null() { 
     panic!("Could not access data from memory mapped file") 
    } 

    let src = "Hello!"; 
    ptr::copy_memory(data, src.as_ptr(), src.as_bytes().len()); 
} 

Chương trình này không thành công với

Process didn't exit successfully: `target/mmap` (status=4) 

khi gọi ptr::copy_memory hoặc bất kỳ hoạt động khác trên dữ liệu.

  • Lý do tôi không thể ghi (hoặc đọc) dữ liệu từ MemoryMap là gì?
  • Cách sử dụng MemoryMap đúng cách là gì?
+3

Ý anh là gì bởi "thất bại khi gọi ..."? Có lỗi trình biên dịch, lỗi thời gian chạy, thông báo lỗi, v.v ... không? – delnan

+0

Bạn có muốn lưu các sửa đổi về tệp không? – Shepmaster

+0

@delnan, đã cập nhật câu hỏi với thông báo lỗi – mkhq

Trả lời

10

Bạn đang thiếu hai phần chính:

  1. mmapdoesn't allocate any space on its own, vì vậy bạn cần phải thiết lập một số không gian trong file. Nếu không có điều này, tôi có được Illegal instruction: 4 khi chạy trên OS X.

  2. MemoryMap là private by default vì vậy bạn cần phải đánh dấu các bản đồ như công để thay đổi được ghi lại vào file (tôi giả sử bạn muốn viết để được lưu). Nếu không có mã này, mã sẽ chạy, nhưng tệp sẽ không bao giờ thay đổi.

Dưới đây là một phiên bản làm việc cho tôi:

#![feature(path,io,os,std_misc,core,libc)] 

use std::os; 
use std::ptr; 
use std::old_io as io; 
use std::os::unix::prelude::AsRawFd; 
use std::os::MapOption; 

extern crate libc; 

fn main() { 
    let size = 1024*1024; 

    let path = Path::new("test.mmap"); 
    let mut f = io::File::open_mode(&path, io::Open, io::ReadWrite).unwrap(); 

    // Allocate space in the file first 
    f.seek(size as i64, io::SeekStyle::SeekSet).unwrap(); 
    f.write_u8(0).unwrap(); 
    f.seek(0, io::SeekStyle::SeekSet).unwrap(); 

    let mmap_opts = &[ 
     // Then make the mapping *public* so it is written back to the file 
     MapOption::MapNonStandardFlags(libc::consts::os::posix88::MAP_SHARED), 
     MapOption::MapReadable, 
     MapOption::MapWritable, 
     MapOption::MapFd(f.as_raw_fd()), 
    ]; 

    let mmap = os::MemoryMap::new(size, mmap_opts).unwrap(); 

    let data = mmap.data(); 

    if data.is_null() { 
     panic!("Could not access data from memory mapped file") 
    } 

    let src = "Hello!"; 
    let src_data = src.as_bytes(); 

    unsafe { 
     ptr::copy_memory(data, src_data.as_ptr(), src_data.len()); 
    } 
} 
6

Up lên phiên bản date:

use std::ptr; 
use std::fs; 
use std::io::{Write, SeekFrom, Seek}; 
use std::os::unix::prelude::AsRawFd; 
use mmap::{MemoryMap, MapOption}; 

// from crates.io 
extern crate mmap; 
extern crate libc; 

fn main() { 
    let size: usize = 1024*1024; 

    let mut f = fs::OpenOptions::new().read(true) 
             .write(true) 
             .create(true) 
             .open("test.mmap") 
             .unwrap(); 

    // Allocate space in the file first 
    f.seek(SeekFrom::Start(size as u64)).unwrap(); 
    f.write_all(&[0]).unwrap(); 
    f.seek(SeekFrom::Start(0)).unwrap(); 

    let mmap_opts = &[ 
     // Then make the mapping *public* so it is written back to the file 
     MapOption::MapNonStandardFlags(libc::consts::os::posix88::MAP_SHARED), 
     MapOption::MapReadable, 
     MapOption::MapWritable, 
     MapOption::MapFd(f.as_raw_fd()), 
    ]; 

    let mmap = MemoryMap::new(size, mmap_opts).unwrap(); 

    let data = mmap.data(); 

    if data.is_null() { 
     panic!("Could not access data from memory mapped file") 
    } 

    let src = "Hello!"; 
    let src_data = src.as_bytes(); 

    unsafe { 
     ptr::copy(src_data.as_ptr(), data, src_data.len()); 
    } 
} 
+0

Tôi gặp lỗi [E0433]: không giải quyết được. Không thể tìm thấy 'consts' trong 'libc' đang cố gắng biên dịch. Thay đổi cố định 'libc :: consts :: os :: posix88 :: MAP_SHARED' thành' libc :: MAP_SHARED'. –

Các vấn đề liên quan