2017-02-12 12 views
6

एक बाइनरी फ़ाइल-प्रारूप में लिखते समय, यह जांचने में सक्षम होता है कि कितने बाइट्स लिखे गए हैं (उदाहरण के लिए संरेखण के लिए), या केवल नेस्टेड फ़ंक्शंस को सही मात्रा में डेटा लिखा है।'std :: io :: लिखें' का उपयोग करते समय कितने बाइट लिखे गए हैं इसका ट्रैक कैसे रखें?

क्या यह जानने के लिए std::io::Write का निरीक्षण करने का कोई तरीका है? यदि नहीं, तो लेखक को लपेटने के लिए एक अच्छा तरीका क्या होगा ताकि यह ट्रैक कर सके कि कितने बाइट लिखे गए हैं?

उत्तर

7

Write में दो आवश्यक विधियां हैं: write और flush। चूंकि write पहले से ही लिखा बाइट की संख्या देता है, तो आप सिर्फ ट्रैक है कि:

use std::io::{self, Write}; 

struct ByteCounter<W> { 
    inner: W, 
    count: usize, 
} 

impl<W> ByteCounter<W> 
    where W: Write 
{ 
    fn new(inner: W) -> Self { 
     ByteCounter { 
      inner: inner, 
      count: 0, 
     } 
    } 

    fn into_inner(self) -> W { 
     self.inner 
    } 

    fn bytes_written(&self) -> usize { 
     self.count 
    } 
} 

impl<W> Write for ByteCounter<W> 
    where W: Write 
{ 
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> { 
     let res = self.inner.write(buf); 
     if let Ok(size) = res { 
      self.count += size 
     } 
     res 
    } 

    fn flush(&mut self) -> io::Result<()> { 
     self.inner.flush() 
    } 
} 

fn main() { 
    let out = std::io::stdout(); 
    let mut out = ByteCounter::new(out); 
    writeln!(&mut out, "Hello, world! {}", 42).unwrap(); 
    println!("Wrote {} bytes", out.bytes_written()); 
} 

यह नहीं प्रतिनिधि write_all या write_fmt के लिए महत्वपूर्ण है, क्योंकि इन बाइट्स की गिनती नहीं लौटाते हैं। उन्हें प्रतिनिधि बनाना बाइट्स को लिखा जाना चाहिए और ट्रैक नहीं किया जाएगा।

+0

यह एक उत्कृष्ट जवाब भी, दोनों के रूप में सही चिह्नित करने के लिए अच्छा होगा है! – ideasman42

+0

@ ideasman42 यदि आप इसे उत्तर के रूप में चिह्नित करते हैं तो मुझे कोई फर्क नहीं पड़ता, क्योंकि यह भी लागू होता है यदि 'खोज' लागू नहीं किया गया है या नहीं किया जा सकता है। – wimh

+0

@ विमह एह, मुझे पता नहीं। स्वीकार करना जो कुछ भी ओपी को उनके विशिष्ट मामले में सबसे ज्यादा मदद करता है। उपरोक्त उत्तर में आते हैं कि भविष्य के लोग उपयोगी पाते हैं। – Shepmaster

5

प्रकार आप लिखते हैं std::io::Seek लागू करता है करने के लिए हैं, तो आप वर्तमान स्थिति प्राप्त करने के लिए seek उपयोग कर सकते हैं:

pos = f.seek(SeekFrom::Current(0))?; 

Seekstd::fs::File द्वारा कार्यान्वित किया जाता है (और std::io::BufWriter अगर लिपटे प्रकार Seek लागू करता है भी)।


तो फ़ंक्शन हस्ताक्षर:

use ::std::io::{Write, Seek, SeekFrom, Error}; 

fn my_write<W: Write>(f: &mut W) -> Result<(), Error> { ... } 

आवश्यकताओं Seek विशेषता है करने के लिए कहा:

fn my_write<W: Write + Seek>(f: &mut W) -> Result<(), Error> { ... } 
संबंधित मुद्दे