2012-01-16 17 views
8

पर फ़्रेड/fwrite के साथ फ़ाइल की प्रतिलिपि बनाने का प्रदर्शन मैं कोड के एक टुकड़े के सामने हूं, जो एक फ़ाइल को यूएसबी डिवाइस पर कॉपी करता है। के बाद भाग महत्वपूर्ण है:यूएसबी

while((bytesRead = fread(buf, 1, 16*1024, m_hSource)) && !bAbort) { 
    // write to target 
    long bytesWritten = fwrite(buf, 1, bytesRead, m_hTarget); 

    m_lBytesCopied += bytesWritten; 

बात है, ग्राहक ने कहा, यह सामान्य पीसी < को सुंदर की तुलना में धीमी है -> यूएसबी गति। मैंने इसे कोड नहीं किया, इसलिए यह मेरा काम है, अनुकूलित करने के लिए।

तो मैं सोच रहा था, अगर यह पूरी फ़ाइल को पहले पढ़ने के लिए बेहतर तरीका है और फिर फ़ाइल को एक चरण में लिखें। लेकिन मुझे नहीं पता कि यह कैसे त्रुटि-प्रवण होगा। कोड प्रत्येक कॉपीस्टेप के बाद भी जांच करता है यदि सभी बाइट्स सही ढंग से लिखे गए हैं, जिससे प्रक्रिया धीमा हो सकती है।

मैं सी ++ & हार्डवेयर गुरु नहीं हूं, इसलिए मैं आपसे पूछ रहा हूं, मैं चीजों को कैसे गति दे सकता हूं और प्रतिलिपि को सफल रख सकता हूं।

+2

बाधा के लिए कहीं और देखें। आपको बफर आकार बदलने में थोड़ा सुधार हो सकता है, लेकिन आपकी समस्या शायद कुछ और है। –

+0

ठीक है, यह एकमात्र ऐसा हिस्सा है जो इस विशेष समस्या के साथ कुछ कर रहा है। तो यह केवल कोड हो सकता है। –

+0

चेक को हटाएं कि बाइट सही तरीके से लिखे गए थे। यदि आप पहले लिखने पर भरोसा नहीं कर सकते हैं, तो आप सत्यापन के लिए उपयोग किए गए निम्नलिखित पढ़ने पर भरोसा नहीं कर सकते हैं। (मुझे लगता है कि आप बाइट्स की जांच कर रहे हैं त्रुटियों के लिए लिखित।) –

उत्तर

3
  1. बड़े चंक में पढ़ने/लिखने का प्रयास करें। 16 एम, 32 एम फाइल कॉपी करने के लिए बुरा नहीं है।
  2. तुम सिर्फ फ़ाइल आप हमेशा आह्वान कर सकते हैं प्रतिलिपि बनाना चाहते हैं तो system() यह तेजी से हो जाएगा।
  3. कोड प्रत्येक प्रतिलिपि के बाद भी जांच करता है यदि सभी बाइट्स सही ढंग से लिखे गए हैं, जिससे प्रक्रिया धीमा हो सकती है।

    आप हैश बड़े हिस्से के बनाकर इसे देख सकते हैं। फाइल को 64 एम भाग में विभाजित करने की तरह। फिर उन हिस्सों के हैंश से मेल खाते हैं। बिटोरेंट प्रोटोकॉल में यह सुविधा है।

  4. आप mmap या MapViewOfFile उपलब्ध है, तो नक्शा फ़ाइल पहले। फिर इसे यूएसबी पर लिखें। इस तरह पढ़ने के ऑपरेशन को कर्नेल द्वारा संभाला जाएगा।

  5. केरेक ने mmap पर memcpy का उपयोग करने के बारे में टिप्पणी की। एड फ़ाइल के साथ बहुत अच्छा लगता है।

यह भी ध्यान दें कि, हालिया ऑपरेटिंग सिस्टम यूएसबी स्टिक को हटाए जाने पर लिखते हैं। हटाने से पहले यह सिर्फ एक कैश में डेटा लिखता है। तो ओएस से कॉपी तेजी से दिखाई दे सकता है।

+1

# 4 अच्छा लगता है: मेमोरी-मैप और 'memcpy' का उपयोग करें। –

+0

@KerrekSB +1। 2 'mmap'ed फ़ाइल के साथ' memcpy' एक अच्छा विकल्प प्रतीत होता है। मेरा प्रश्न अपडेट किया गया। –

1

ओवरलैपिंग पढ़ने और लिखने के बारे में क्या?

वर्तमान कोड में, कुल समय time(read original) + time(write copy) है, यदि आप पहले ब्लॉक को पढ़ते हैं, तो इसे लिखते समय इसे दूसरी ब्लॉक पढ़ना शुरू होता है, आदि। आपका कुल समय max(time(read original), time(write copy)) होगा (साथ ही पहले पढ़ने/लिखने का समय और अंतिम ब्लॉक जो पाइपलाइन नहीं होंगे)।

पढ़ना और लिखना एक ही समय में कम या ज्यादा समय लेना लगभग आधा समय हो सकता है।

आप इसे दो धागे या एसिंक्रोनस आईओ के साथ कर सकते हैं। दुर्भाग्यवश, थ्रेड और एसिंक आईओ प्लेटफार्म निर्भर हैं, इसलिए आपको अपने सिस्टम मैनुअल की जांच करनी होगी या उपयुक्त पोर्टेबल पुस्तकालयों को चुनना होगा।

+0

AFAIK, यूएसबी I/O भी अधिकतर मंच निर्भर है, है ना? –

+0

@ AndréCaron मुझे लगता है कि यदि आप एक ड्राइवर बना रहे हैं, लेकिन इस मामले में मुझे लगता है कि यह सिर्फ फाइल सिस्टम तक पहुंच रहा है, इसलिए आप फ़ाइलों को 'fopen' कर सकते हैं (और यह मानक है)। – fortran

0

मैं कुछ ओएस विशिष्ट कार्यों के साथ जाऊंगा जो निश्चित रूप से यह तेज़ी से करते हैं कि सी/सी ++ कार्यों के साथ ही लिखा गया कुछ भी।

लिनक्स के लिए यह sendfile फ़ंक्शन हो सकता है। विंडोज CopyFile के लिए काम करेगा।

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