File.Move काम नहीं करता है - फ़ाइल पहले से ही मौजूद है


86

मुझे एक फ़ोल्डर मिला है:

c: \ परीक्षण

मैं इस कोड की कोशिश कर रहा हूँ:

File.Move(@"c:\test\SomeFile.txt", @"c:\test\Test");

मुझे अपवाद मिलता है:

फ़ाइल पहले से ही मौजूद है

आउटपुट निर्देशिका निश्चित रूप से मौजूद है और इनपुट फ़ाइल है।


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

9
लगता है कि त्रुटि आपको बता रही है कि वास्तव में क्या गलत है।
जोश

@ जोश नहीं। ऐसा लगता है कि विंडोज नॉन-पॉसिक्स फाइलसिस्टम का व्यवहार कर रहा है, जो एक साधारण पोर्टेबल ट्रांजैक्शनल फाइल अपडेट पैटर्न / रूटीन को असंभव बना देता है।
बिंकी

@binki POSIX अप्रासंगिक है (क्या आप परमाणु परिचालनों का उल्लेख कर रहे हैं ?), NTFS रियल ट्रांसेक्शनल ऑपरेशंस का समर्थन करता है , जैसा कि रोलबैक-एंड- ए -ओरिजिनल-फाइल-कंटेंट-बैक में है। दूसरों के रूप में उत्तर दिया, Win32 करता है की जगह के साथ कदम अनुमति देते हैं। .NET का File.Move है जो कार्यक्षमता प्रदान नहीं करता है। आप पुस्तकालयों के साथ बदलें और लेन-देन के संचालन के साथ दोनों ले सकते हैं जैसे कि अल्फा एफएफएस
पैनागोटिस कानावोस

2
@ बिंकी किसी भी मामले में अलग-अलग फ़ाइल सिस्टम पर व्यवहार को अच्छी तरह से परिभाषित करती है , कोई फर्क नहीं पड़ता कि फ़ोरम चर्चाएं क्या कहती हैं। File.Move Ex या Transacted विधियों को कॉल नहीं करता है, यह FAT है, जिसे नजरअंदाज नहीं किया जा सकता है क्योंकि यह अभी भी मेमोरी कार्ड द्वारा उपयोग किया जाता है, परमाणु नहीं है और यह समान व्यवहार नहीं करता है । नाम मेटाडेटा ऑपरेशन नहीं हैं और वास्तविक डेटा आंदोलन की आवश्यकता है। और लेनदेन और कॉपी-ऑन-राइट के बारे में भूल जाओ। नहीं एक महान निर्णय imho
Panagiotis Kanavos

जवाबों:


62

आपको इसे किसी अन्य फ़ाइल (एक फ़ोल्डर के बजाय) में स्थानांतरित करने की आवश्यकता है, इसका उपयोग नाम बदलने के लिए भी किया जा सकता है।

ले जाएँ:

File.Move(@"c:\test\SomeFile.txt", @"c:\test\Test\SomeFile.txt");

नाम बदलें:

File.Move(@"c:\test\SomeFile.txt", @"c:\test\SomeFile2.txt");

आपके उदाहरण में "फ़ाइल पहले से मौजूद है" इसका कारण यह है, क्योंकि एक्सटेंशन के बिना C:\test\Testफ़ाइल बनाने की कोशिश की जाती है Test, लेकिन ऐसा नहीं कर सकते क्योंकि एक फ़ोल्डर पहले से ही समान नाम के साथ मौजूद है।


138

आपको क्या चाहिए:

if (!File.Exists(@"c:\test\Test\SomeFile.txt")) {
    File.Move(@"c:\test\SomeFile.txt", @"c:\test\Test\SomeFile.txt");
}

या

if (File.Exists(@"c:\test\Test\SomeFile.txt")) {
    File.Delete(@"c:\test\Test\SomeFile.txt");
}
File.Move(@"c:\test\SomeFile.txt", @"c:\test\Test\SomeFile.txt");

यह या तो होगा:

  • यदि फ़ाइल गंतव्य स्थान पर मौजूद नहीं है, तो फ़ाइल को सफलतापूर्वक स्थानांतरित करें, या;
  • यदि फ़ाइल गंतव्य स्थान पर मौजूद है, तो उसे हटा दें, फिर फ़ाइल को स्थानांतरित करें।

संपादित करें: मुझे अपना उत्तर स्पष्ट करना चाहिए, भले ही यह सबसे अधिक उत्कीर्ण हो! File.Move का दूसरा पैरामीटर गंतव्य फ़ाइल होना चाहिए - एक फ़ोल्डर नहीं । आप दूसरे पैरामीटर को डेस्टिनेशन फोल्डर के रूप में निर्दिष्ट कर रहे हैं, कि डेस्टिनेशन फाइलनेम - जो कि File.Move के लिए आवश्यक है। तो, आपका दूसरा पैरामीटर होना चाहिए c:\test\Test\SomeFile.txt


निश्चित रूप से जाँच करने की आवश्यकता नहीं है कि क्या फ़ाइल वहाँ नहीं है, क्योंकि वह जाँच कर रहा है और फ़ाइल वहाँ नहीं है। जब वह किसी अन्य फ़ोल्डर में ले जाने की कोशिश कर रहा हो, तो फ़ाइल नाम को गंतव्य फ़ोल्डर में नहीं जोड़ने के कारण अपवाद होता है।
हादी एस्कंदरी

3
यदि आपका ऐप मल्टी थ्रेडेड है (या आपकी फ़ाइलों पर काम करने वाली अन्य प्रक्रियाएँ हैं) तो आप संभवतः "इफ़ (यदि हटाएं) कोड" का उपयोग करके भी एक ही अपवाद प्राप्त कर सकते हैं। चूंकि अभी भी समय का एक स्थान है जहां एक और धागा / प्रक्रिया एक फ़ाइल को हटाए जाने के बाद वापस रख सकता है, फिर आप अपना कदम रखते हैं, और फिर वैसे भी अपवाद प्राप्त करें। सिर्फ मन में असर करने वाली बात :-)
बट्टेव

11
यह उत्तर अभी भी अधिकांश लोगों के लिए मान्य है कि Google किसी मौजूदा फ़ाइल को अधिलेखित करने की कोशिश कर रहा है। इस पूर्वानुमान में अधिकांश लोगों के पास ओपी की तरह वाक्य रचना / टाइप-ओ मुद्दा नहीं है।
WEFX

1
@ v.oddou दिलचस्प है, अगर फ़ाइल मौजूद नहीं है, File.Delete वास्तव में सही ढंग से काम करता है और कुछ भी नहीं करता है। यदि इसके बजाय, पथ में कोई भी निर्देशिका मौजूद नहीं है, तो आपको एक DirectoryNotFoundException मिलती है।
ब्रैंडन बार्कले

2
@JirkaHanika आप बदल सकते हैं अगर (File.Exists) जबकि (File.Exists)।
ब्रैंडन बार्कले

38

व्यक्तिगत रूप से मुझे यह विधि पसंद है। यह गंतव्य पर फ़ाइल को अधिलेखित कर देगा, स्रोत फ़ाइल को हटा देगा और प्रतिलिपि के विफल होने पर स्रोत फ़ाइल को हटाने से भी रोक देगा।

string source = @"c:\test\SomeFile.txt";
string destination = @"c:\test\test\SomeFile.txt";

try
{
    File.Copy(source, destination, true);
    File.Delete(source);
}
catch
{
    //some error handling
}

4
यह छोटी फ़ाइलों (और परमाणु चाल के लिए कोई आवश्यकता नहीं) के लिए ठीक है, लेकिन बड़ी फ़ाइलों या मामलों के लिए जब आपको यह सुनिश्चित करने की आवश्यकता होती है कि आप डुप्लिकेट के साथ समाप्त नहीं होंगे, तो यह समस्याग्रस्त है।
नदी सत्य

आप क्यों पसंद करते File.Copy , File.Deleteहैं File.Move?
जॉन पीटरर

6
File.Move doesn t एक अधिलेखित विकल्प है।
मिशेल

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

1
क्या यह बड़ी फ़ाइलों के लिए बहुत कम प्रदर्शन नहीं होगा? यदि स्रोत और गंतव्य एक ही भौतिक आयतन पर हैं, तो आप बिना किसी कारण के दूसरी प्रति बना रहे हैं और फिर मूल को हटा रहे हैं, जबकि File.Move () स्रोत और गंतव्य एक ही वॉल्यूम पर होने पर अतिरिक्त कार्य करने से बचेंगे।
ब्रैड वेस्टनेस

18

आप P / Invoke कर सकते हैं MoveFileEx()- ( ) के लिए 11 पास करेंflagsMOVEFILE_COPY_ALLOWED | MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH

[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("kernel32.dll", SetLastError=true, CharSet=CharSet.Unicode)]
static extern bool MoveFileEx(string existingFileName, string newFileName, int flags);

या, आप बस कॉल कर सकते हैं

Microsoft.VisualBasic.FileIO.FileSystem.MoveFile(existingFileName, newFileName, true);

संदर्भ के रूप में Microsoft.VisualBasic जोड़ने के बाद।


पूरी तरह से ठीक है अगर एप्लिकेशन केवल विंडोज पर चल रहा है। यह शायद उन लोगों के लिए एक अच्छा जवाब है जो सोम पी / इनवोक की कोशिश करने के इच्छुक हैं।
टोड

9

यदि फ़ाइल वास्तव में मौजूद है और आप इसे नीचे दिए गए कोड का उपयोग करना चाहते हैं:

string file = "c:\test\SomeFile.txt"
string moveTo = "c:\test\test\SomeFile.txt"

if (File.Exists(moveTo))
{
    File.Delete(moveTo);
}

File.Move(file, moveTo);

4

File.Move के लिए डॉक्स के अनुसार "मौजूद होने पर कोई अधिलेखित नहीं होता है" पैरामीटर। आपने गंतव्य फ़ोल्डर निर्दिष्ट करने का प्रयास किया , लेकिन आपको पूर्ण फ़ाइल विनिर्देश देना होगा।

डॉक्स को फिर से पढ़ना ("एक नया फ़ाइल नाम निर्दिष्ट करने के लिए विकल्प प्रदान करना"), मुझे लगता है कि गंतव्य फ़ोल्डर कल्पना में बैकस्लैश जोड़ना काम कर सकता है।


और डॉक्स नोट करते हैं कि यदि आप उसी डायरेक्टरी में उसी नाम की फाइल को ले जाकर किसी फाइल को बदलने का प्रयास करते हैं, तो IOException को फेंक दिया जाता है। उस उद्देश्य के लिए, Move(String, String, Boolean)बजाय कॉल करें । लेकिन ऐसा लगता है कि एक गलती है?
केविन शार्नरहॉस्ट

@KevinScharnhorst यह उत्तर 2011 था। अब प्रलेखन में शामिल हैं। ओवरराइट के साथ मूव के लिए .net Core 3.0 समर्थन।
टोड

4

1)। C # के साथ .net Core 3.0 और उसके बाद, अब एक तीसरा बूलियन पैरामीटर है:

देख https://docs.microsoft.com/en-us/dotnet/api/system.io.file.move?view=netcore-3.1

In .NET Core 3.0 and later versions, you can call Move(String, String, Boolean) setting the parameter overwrite to true, which will replace the file if it exists.

2) .Net के अन्य सभी संस्करणों के लिए, https://stackoverflow.com/a/42224803/887092 सबसे अच्छा जवाब है। ओवरराइट के साथ कॉपी करें, फिर स्रोत फ़ाइल को हटा दें। यह बेहतर है क्योंकि यह इसे एक परमाणु संचालन बनाता है। (मैंने इसके साथ एमएस डॉक्स को अपडेट करने का प्रयास किया है)


2

कोशिश करो Microsoft.VisualBasic.FileIO.FileSystem.MoveFile(Source, Destination, True)। अंतिम पैरामीटर ओवरराइट स्विच है, जिसमें System.IO.File.Moveनहीं है।


2
यहाँ पहले से ही एक और उत्तर है जो समान है जो एक ही स्टैकओवरफ़्लो का
JG में SD

यह वही उत्तर है जो समान सुझाव देता है: stackoverflow.com/a/38372760/887092 , stackoverflow.com/a/42224803/1236734
टोड

1

यदि आपके पास नए स्थान में पहले से मौजूद फ़ाइल को हटाने का विकल्प नहीं है, लेकिन फिर भी मूल स्थान से हटने और हटाने की आवश्यकता है, तो यह नाम बदलने की चाल काम कर सकती है:

string newFileLocation = @"c:\test\Test\SomeFile.txt";

while (File.Exists(newFileLocation)) {
    newFileLocation = newFileLocation.Split('.')[0] + "_copy." + newFileLocation.Split('.')[1];
}
File.Move(@"c:\test\SomeFile.txt", newFileLocation);

यह एकमात्र मानता है '।' फ़ाइल नाम एक्सटेंशन से पहले है। यह एक्सटेंशन से पहले फ़ाइल को दो में विभाजित करता है, "_copy" संलग्न करता है। के बीच में। यह आपको फ़ाइल को स्थानांतरित करने देता है, लेकिन एक प्रतिलिपि बनाता है यदि फ़ाइल पहले से मौजूद है या प्रतिलिपि की एक प्रतिलिपि पहले से मौजूद है, या प्रतिलिपि की प्रतिलिपि मौजूद है ...;)

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.