How to cut large Vec <i32> like & [u8]?

I do not know how to convert Vec<i32> to slice &[u8] .

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

I want to write a large Vec<i32> to a file so that I can read it in the future.

+4
source share
2 answers

You can use 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>(), ) }; 

Following the comments on this answer, you should wrap this code in a function and return the return value so that you can use the borrower verification tool as far as possible:

 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>(), ) } } 
+9
source

Starting with Rust 1.30, the best solution is to use slice::align_to :

 fn main() { let v: Vec<i32> = vec![1; 8]; let (head, body, tail) = unsafe { v.align_to::<u8>() }; assert!(head.is_empty()); assert!(tail.is_empty()); println!("{:#x?}", body); } 

This handles cases where the alignment of the first type and the second type do not match. In this example, I guarantee that the alignment of i32 greater than u8 through assert! statements.


I took @swizards answer and ran with it to get the other side of the coin - reading the vector back:

 use std::fs::File; use std::io::{Read, Write}; use std::{mem, slice}; 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) } 
+5
source

Source: https://habr.com/ru/post/983793/


All Articles