2016-12-09 6 views
12

मुझे एक पूरी तरह से मेमोरी ऑब्जेक्ट की आवश्यकता है जिसे मैं BufReader और BufWriter पर दे सकता हूं। कुछ पाइथन की StringIO की तरह। मैं सामान्य रूप से File एस के साथ उपयोग की जाने वाली विधियों का उपयोग करके ऐसी वस्तु से लिखना और पढ़ना चाहता हूं।एक मेमोरी ऑब्जेक्ट कैसे बनाएं, जिसे जंग में रीडर या राइटर के रूप में उपयोग किया जा सके?

क्या मानक पुस्तकालय का उपयोग करके ऐसा करने का कोई तरीका है?

उत्तर

13

वास्तव में एक तरीका है। Cursor<T> से मिलें!

प्रलेखन में आप निम्नलिखित impls देखते हैं कि देख सकते हैं:,

impl<T> Seek for Cursor<T> where T: AsRef<[u8]> 
impl<T> Read for Cursor<T> where T: AsRef<[u8]> 
impl Write for Cursor<Vec<u8>> 
impl<T> AsRef<[T]> for Vec<T> 

इस आप देख सकते हैं कि तुम सिर्फ एक साधारण फ़ाइल के रूप में प्रकार Cursor<Vec<u8>> उपयोग कर सकते हैं से क्योंकि Read, Write और Seek उस प्रकार के लिए लागू किए गए हैं!

लिटिल उदाहरण (Playground):

use std::io::{Cursor, Read, Seek, SeekFrom, Write}; 

// Create fake "file" 
let mut c = Cursor::new(Vec::new()); 

// Write into the "file" and seek to the beginning 
c.write_all(&[1, 2, 3, 4, 5]).unwrap(); 
c.seek(SeekFrom::Start(0)).unwrap(); 

// Read the "file's" contents into a vector 
let mut out = Vec::new(); 
c.read_to_end(&mut out).unwrap(); 

println!("{:?}", out); 

एक अधिक उपयोगी उदाहरण के लिए, प्रलेखन ऊपर लिंक की जाँच करें।

use std::io::BufRead; 
use std::io::BufReader; 
use std::io::Read; 

fn read_buff<R: Read>(mut buffer: BufReader<R>) { 
    let mut data = String::new(); 
    let _ = buffer.read_line(&mut data); 

    println!("read_buff got {}", data); 
} 

fn main() { 
    read_buff(BufReader::new("Potato!".as_bytes())); 
} 

यह प्रिंट read_buff got Potato!:

1

आप के साथ BufReader उपयोग करने के लिए एक में स्मृति String, आप as_bytes() विधि का उपयोग कर सकते हैं। इस मामले के लिए कर्सर का उपयोग करने की कोई आवश्यकता नहीं है।

एक में स्मृति BufWriter साथ String, आप as_mut_vec विधि का उपयोग कर सकते हैं का उपयोग करें। दुर्भाग्यवश यह unsafe है और मुझे कोई अन्य रास्ता नहीं मिला है। मुझे वेक्टर का उपभोग करने के बाद Cursor दृष्टिकोण पसंद नहीं है और मुझे के साथ Cursor का उपयोग करने का कोई तरीका नहीं मिला है।

use std::io::BufWriter; 
use std::io::Write; 

pub fn write_something<W: Write>(mut buf: BufWriter<W>) { 
    buf.write("potato".as_bytes()); 
} 

#[cfg(test)] 
mod tests { 
    use super::*; 
    use std::io::{BufWriter}; 

    #[test] 
    fn testing_bufwriter_and_string() { 
     let mut s = String::new(); 

     write_something(unsafe { BufWriter::new(s.as_mut_vec()) }); 

     assert_eq!("potato", &s); 
    } 
} 
+0

आप [ 'Vec' वापस पाने] (https://doc.rust-lang.org/std/io/struct.Cursor.html#method.into_inner) के बाद आप के साथ किया जाता है कर सकते हैं' Cursor'। – Shepmaster

+0

@ शेमपस्टर ग्रेट! और फिर मैं स्ट्रिंग को कन्फेट करने के लिए ['from_utf8'] (https://doc.rust-lang.org/std/str/fn.from_utf8.html) का उपयोग कर सकता हूं, 'from_utf8' वेक्टर की प्रतिलिपि से बचने के लिए प्रतीत होता है, इसलिए यह कुशल होना चाहिए, शायद 'from_utf8_unchecked' का भी उपयोग कर सकता है जो एक साधारण कदम होना चाहिए। –

संबंधित मुद्दे

 संबंधित मुद्दे