2013-07-16 3 views
12

कुछ ओएस कार्यों मुझे लगता है कि आपके पास POSIX सिस्टम पर के माध्यम से अब देख रहे हैं सी फ़ंक्शन को कॉल की तरह unlink() एक फ़ाइल स्थानांतरित करने के लिए, प्रतीकात्मक फ़ाइलें बनाने के लिए rename(), फ़ाइलों के लिए कठिन लिंक बनाने के लिए symlink(), फ़ाइलें निकालने के लिए link(), लेकिन ... जहां copy() पर एक फ़ंक्शन है?क्या कोई फ़ाइल कॉपी करने के लिए कोई POSIX फ़ंक्शन है?

मुझे पता है कि सामान्य तरीका सिर्फ स्रोत फ़ाइल खोलना है, इसकी सामग्री पढ़ना है, एक गंतव्य फ़ाइल खोलना है और उन्हें वहां डंप करना है। लेकिन मुझे पिछले सभी लोगों को ऐसा कोई उपयोगिता समारोह क्यों नहीं मिल रहा है?

+0

फ़ाइल की प्रतिलिपि बनाना एक लंबा चल रहा है और जटिल संचालन है; यहां तक ​​कि जहां ओएस में सिस्टम-लाइब्रेरी 'कॉपीफाइल' फ़ंक्शन (जैसे विंडोज करता है) है, यह _system call_ के रूप में लागू करने की संभावना नहीं है बल्कि उपयोगिता फ़ंक्शन के रूप में लागू किया जा सकता है। प्रतिलिपि बनाने के कई तरीके हैं, और यूएन * एक्स ने कभी भी चीजों को करने के बारे में बहुत स्पष्ट नहीं चुना है (यानी फ़ाइल कॉपी बनाने के लिए 'प्रतिलिपि') को सुनहरा मार्ग के रूप में बेचें। –

उत्तर

14

जब के बारे में "एक फ़ाइल को कॉपी" बात कर, दो अर्थ विज्ञान मौजूद हैं:

  1. दीप कॉपी - एक नई फ़ाइल से संबद्ध सभी डेटा/मेटाडाटा की एक प्रति युक्त फ़ाइल के निर्माण, हालांकि फाइल सिस्टम संरचनाओं इस
  2. उथला कॉपी - एक नया निर्देशिका प्रविष्टि के निर्माण/फ़ाइल एक ही डेटा की चर्चा करते हुए (और संभव कुछ या मेटाडाटा के सभी) स्रोत फ़ाइल के रूप में

विंडोज/डॉस फाइल सिस्टम पारंपरिक रूप से कोई "उथली प्रतिलिपि" तंत्र नहीं था - लेकिन यूएन * एक्स हमेशा हार्ड लिंक के रूप में था। मौजूदा "फ़ाइल डेटा" एक नए नाम से करने के लिए एक नया संदर्भ स्थापित करने के लिए - - यानी, किसी उथले प्रतिलिपि कर

तो POSIX/संयुक्त राष्ट्र * एक्स link(2) सिस्टम कॉल है।

एक "गहरी प्रति" प्रणाली कॉल केवल तभी समझ में आता है जब "तेज गहरी प्रति" तंत्र है - उदाहरण के लिए, ऐसे मामलों में जहां अंडरलेइंग फाइल सिस्टम फ़ाइल-स्तरीय क्लोनिंग करने के लिए deduplucation की तरह कुछ लागू करता है।

अन्यथा, इस तरह के फ़ंक्शन को लाइब्रेरी कार्यान्वयन को "गिरावट" (वापस गिरना) होगा।

यूएन * एक्स तंत्र फाइल सिस्टम-विशिष्ट के रूप में कुछ के लिए अनुमति देने के लिए ioctl(), "आई/ओ विस्तारशीलता का रसोई सिंक" है। उदाहरण के लिए, यदि उपलब्ध हो, तो इस सुविधा का उपयोग करने के लिए, फ़ाइलों को कॉपी करने के लिए, this GNU coreutils post देखें, बीटीआरएफएस पर फ़ाइल क्लोनिंग का उपयोग करने के लिए एक वृद्धि अनुरोध के साथ।

यह देखते हुए कि विंडोज 'CopyFile एक कॉलबैक के बिना वास्तव में CopyFileEx है, मैं दृढ़ता से संदेह यह वास्तव में एक सिस्टम कॉल है; यह एक उपयोगिता समारोह है। Wine Windows Emulator के लिए, आप kernel32.dll स्रोत कार्यान्वयन की जांच कर सकते हैं, उदाहरण के लिए शराब स्रोतों, dlls/kernel32/path.c में पाएं किया जा सकता है।
वियोजन/Decompiling विंडोज 'वास्तविक kernel.dll, माइक्रोसॉफ्ट के लाइसेंस के तहत अनुमति नहीं है, इसलिए मैं कानूनी तौर पर दावा नहीं कर विंडोज खुद ही करता है कि अर्थात CopyFile एक userland कार्यान्वयन, नहीं एक सिस्टम कॉल है।

संयुक्त राष्ट्र में Windows और संयुक्त राष्ट्र * एक्स तुलना करने के लिए फिर से यहाँ ... नहीं सब कुछ * एक्स libc एक सिस्टम कॉल है, यही कारण है कि संयुक्त राष्ट्र * एक्स manpages के बीच धारा 2 (सिस कॉल) और धारा 3 (क्रम भेद है लाइब्रेरी इंटरफेस)। विंडोज़ पर kernel.dll में फ़ंक्शंस के लिए भी यह सच है - उनमें से कुछ "प्रत्यक्ष पाथथ्रू" हैं जबकि अन्य अधिक जटिल "उपयोगिता कार्य" एकल सिस्टम कॉल के माध्यम से लागू नहीं किए गए हैं।

+0

कुछ अलग-अलग (अधिकांश?) अधिकारियों में, पूरी तरह से अलग-अलग चीज़ों के बारे में, यह ऐसा करने के लिए पूरी तरह से कानूनी है (यहां तक ​​कि स्पष्ट रूप से कहा गया है!)। और यूरोप में ईयूएलए का कोई कानूनी अर्थ नहीं है। ** अस्वीकरण: ** यदि आप ऐसा करना चाहते हैं, तो मैं वकील नहीं हूं, आपको कानूनी वकील इत्यादि आदि लेना चाहिए ... –

+0

@ टिम सीस: मैंने उस पर कोई दावा नहीं किया - केवल यह कहकर कि _here_, मैंने जीता ' माइक्रोसॉफ्ट द्वारा प्रदत्त गैर-ओपनसोर्स बाइनरी के किसी भी डिस्सेप्लर को उद्धृत करने के लिए यह बिल्कुल वही करता है। –

1

आपको फ़ाइल की प्रतिलिपि बनाने के लिए उपयोगिता फ़ंक्शन नहीं मिल रहा है क्योंकि इसकी आवश्यकता नहीं है; इसे 'स्पेयर पार्ट्स' से बनाया जा सकता है। unlink() और symlink() जैसे कार्यों को अन्य कार्यों के संदर्भ में नहीं बनाया जा सकता है, जबकि एक hypothetical copy_file() जैसे कार्यों (तो आपको चाहिए)।

को देखते हुए दो खुले फ़ाइल धाराओं, पढ़ने के लिए f1 और f2 लिखने के लिए है, तो आप इस्तेमाल कर सकते हैं:

void fcopy(FILE *f1, FILE *f2) 
{ 
    char   buffer[BUFSIZ]; 
    size_t   n; 

    while ((n = fread(buffer, sizeof(char), sizeof(buffer), f1)) > 0) 
    { 
     if (fwrite(buffer, sizeof(char), n, f2) != n) 
      err_syserr("write failed\n"); 
    } 
} 

err_syserr() समारोह स्ट्रिंग एक तर्क के रूप में पारित और त्रुटि संदेश से गर्भित सहित त्रुटि रिपोर्टिंग के लिए है errno*; यह वापस नहीं आता है। BUFSIZ को <stdio.h> में परिभाषित किया गया है लेकिन आप एक बड़े मूल्य का उपयोग करना चुन सकते हैं। आप इस तरह की त्रुटि रिपोर्ट नहीं करना पसंद कर सकते हैं, लेकिन सफलता पर फंक्शन 0 और किसी भी विफलता पर फ़ंक्शन वापस कर सकते हैं।

int fcopy(FILE *f1, FILE *f2) 
{ 
    char   buffer[BUFSIZ]; 
    size_t   n; 

    while ((n = fread(buffer, sizeof(char), sizeof(buffer), f1)) > 0) 
    { 
     if (fwrite(buffer, sizeof(char), n, f2) != n) 
      return -1; 
    } 
    return 0; 
} 

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

*वास्तव में, err_syserr() जो एक प्रारूप स्ट्रिंग और अन्य तर्क लेता है, और उसके बाद का वर्णन किया और बाहर निकलता है के रूप में त्रुटि संदेश रिपोर्ट printf() की तरह एक समारोह है।

+1

यह दिलचस्प है कि आप उल्लेख करते हैं आप स्पेयर पार्ट्स में से एक बना सकते हैं, लेकिन फिर आपकी कॉपी संस्करण फ़ाइल विशेषताओं की प्रतिलिपि नहीं बनाता है।सुरक्षा से संबंधित नई फ़ाइल विशेषता एक्सटेंशन भी खो जाएंगे, जैसे मैकोज़क्स जैसे प्लेटफॉर्म पर संसाधन फोर्क होगा, इसलिए आप वास्तव में पोर्टेबल कोड नहीं लिख सकते हैं ... मुझे नहीं पता, ऐसा लगता है कि पॉज़िक्स ने गेंद को यहां गिरा दिया .. –

+0

'सिस्टम (" cp --preserve = सभी file1 file2 ")' – jxh

+0

मैं जो कोड दिखाता हूं वह फाइल नहीं खोलता है, और फ़ाइल खुली या कोड बनाते हैं, जहां आप गुणों जैसी चीजों से निपटेंगे। संसाधन कांटे स्वाभाविक रूप से गैर पोर्टेबल हैं; POSIX उन चीज़ों के व्यवहार के लिए कानून नहीं बनाता है जो इसके बारे में कुछ नहीं जानते हैं। प्लेटफ़ॉर्म-विशिष्ट विकल्पों को खोजने के लिए आप किसी दिए गए प्लेटफ़ॉर्म को देख सकते हैं जो आप चाहते हैं, लेकिन वे पोर्टेबल नहीं होंगे। इसके अलावा, ऐसे कई संभावित व्यवहार हैं जो एपीआई को डिजाइन करना मुश्किल होगा। क्या यह संशोधन समय कॉपी करता है? अनुमतियां? क्या होगा यदि लक्ष्य फ़ाइल पहले से मौजूद है? एक सिम्लिंक है? एसीएल सुरक्षा जानकारी? आदि –

1

POSIX सिस्टम Win32 में CopyFile फ़ंक्शन जैसे सिस्टम कॉल प्रदान नहीं करते हैं, इसलिए Copy_file() फ़ंक्शन को खोजने में अपना समय बर्बाद न करें। यदि आप पहिया को फिर से शुरू नहीं करना चाहते हैं, तो मुझे लगता है कि एक नई प्रक्रिया बनाने के लिए fork() का उपयोग करना और execl() पर कॉल करना एक अच्छा विचार है। इस तरह:

execl("/bin/cp", "-p", src_file, des_file, (char *)0); 
13

मैं लिनक्स पर cp आदेश पर strace चल की कोशिश की और यह वास्तव में दोनों फ़ाइलों को खोलने के लिए और यह एक फ़ाइल से पढ़ता है और 32768 बाइट्स के ब्लॉक में एक दूसरे पर लिखें:

... 
stat64("log", {st_mode=S_IFREG|0644, st_size=352, ...}) = 0 
stat64("copied", 0xbf99e1c0)    = -1 ENOENT (No such file or directory) 
open("log", O_RDONLY|O_LARGEFILE) = 3 
fstat64(3, {st_mode=S_IFREG|0644, st_size=352, ...}) = 0 
open("copied", O_WRONLY|O_CREAT|O_EXCL|O_LARGEFILE, 0644) = 4 
fstat64(4, {st_mode=S_IFREG|0644, st_size=0, ...}) = 0 
read(3, "2012-04-27 22:26:55-0400 [-] Log"..., 32768) = 352 
write(4, "2012-04-27 22:26:55-0400 [-] Log"..., 352) = 352 
read(3, "", 32768)      = 0 
close(4)        = 0 
close(3)        = 0 
... 

तो हाँ, वहाँ कोई सीपी syscall वहाँ नहीं है। उम्मीद है कि यह आपकी मदद करता है।

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