2015-03-13 13 views
2

我不知道如何切割Vec作为& [u8]切片?如何切割一个大的Vec <i32>为&[u8]?

fn main() { 
    let v: Vec<i32> = vec![1; 100_000_000]; 
    let v_bytes: &[u8] = ... 
} 

我问,因为我想写一个大的Vec到一个文件,所以我可以在未来的时间读回来。

+0

我试着使用MEM ::蜕变但没”工作。 – jimjampez 2015-03-13 16:42:32

+2

如果要将数据写入文件,则应使用编码。无论是['bincode'](https://github.com/TyOverby/bincode)还是我自己的['cbor'](https://github.com/BurntSushi/cbor)都可以做得很好。 – BurntSushi5 2015-03-13 16:49:58

+1

您是否担心跨机器或软件版本的数据的排序或可移植性? – Shepmaster 2015-03-13 17:18:28

回答

6

您可以尝试std::slice::from_raw_parts

let v_bytes: &[u8] = unsafe { 
    std::slice::from_raw_parts(v.as_ptr() as *const u8, 
           v.len() * std::mem::size_of::<i32>()) 
}; 

更新

(以下答案评论)

你也可以换这个代码的函数,有返回值借输入vec,以便尽可能使用借用检查器。

fn as_u8_slice(v: &[i32]) -> &[u8] { 
    unsafe { 
     std::slice::from_raw_parts(v.as_ptr() as *const u8, 
            v.len() * std::mem::size_of::<i32>()) 
    } 
} 
+3

将其封装在一个函数中,并且返回值借用输入vec,以便尽可能使用借用检查器。 'unsafe fn as_u8_slice(xs:&[i32]) - >&[u8] {...' – bluss 2015-03-14 10:24:09

+0

你应该真的在限制片的生命期参数。前评论者的建议看起来是最好的方法。 – sellibitze 2015-03-14 12:12:04

+0

谢谢,我已经更新了答案! – swizard 2015-03-14 12:18:56

3

我把@swizards回答,并用它跑一点得到了硬币的另一面 - 阅读载体回:

use std::{mem, slice}; 
use std::fs::File; 
use std::io::{Read, Write}; 

fn as_u8_slice(v: &[i32]) -> &[u8] { 
    let element_size = mem::size_of::<i32>(); 
    unsafe { slice::from_raw_parts(v.as_ptr() as *const u8, v.len() * element_size) } 
} 

fn from_u8(v: Vec<u8>) -> Vec<i32> { 
    let data = v.as_ptr(); 
    let len = v.len(); 
    let capacity = v.capacity(); 
    let element_size = mem::size_of::<i32>(); 

    // Make sure we have a proper amount of capacity (may be overkill) 
    assert_eq!(capacity % element_size, 0); 
    // Make sure we are going to read a full chunk of stuff 
    assert_eq!(len % element_size, 0); 

    unsafe { 
     // Don't allow the current vector to be dropped 
     // (which would invalidate the memory) 
     mem::forget(v); 

     Vec::from_raw_parts(
      data as *mut i32, 
      len/element_size, 
      capacity/element_size, 
     ) 
    } 
} 

fn do_write(filename: &str, v: &[i32]) { 
    let mut f = File::create(filename).unwrap(); 
    f.write_all(as_u8_slice(&v)).unwrap(); 
} 

fn do_read(filename: &str) -> Vec<i32> { 
    let mut f = File::open(filename).unwrap(); 
    let mut bytes = Vec::new(); 

    f.read_to_end(&mut bytes).unwrap(); 

    from_u8(bytes) 
} 

fn main() { 
    let v = vec![42; 10]; 
    do_write("vector.dump", &v); 
    let v2 = do_read("vector.dump"); 

    assert_eq!(v, v2); 
    println!("{:?}", v2) 
}