সি # তে একটি ডিরেক্টরি সম্পূর্ণ সামগ্রী অনুলিপি করুন


524

আমি কোনও ডিরেক্টরি থেকে সম্পূর্ণ ডিরেক্টরি কপির জন্য একটি অবস্থান থেকে অন্য স্থানে অনুলিপি করতে চাই।

System.IOপ্রচুর পুনরাবৃত্তি ছাড়াই ক্লাস ব্যবহার করে এটি করার কোনও উপায় বলে মনে হচ্ছে না ।

ভিবিতে একটি পদ্ধতি রয়েছে যা আমরা ব্যবহার করতে পারি যদি আমরা একটি রেফারেন্স যুক্ত করি Microsoft.VisualBasic:

new Microsoft.VisualBasic.Devices.Computer().
    FileSystem.CopyDirectory( sourceFolder, outputFolder );

এটি একটি বরং কুশ্রী হ্যাক মত মনে হচ্ছে। একটি ভাল উপায় আছে কি?


101
আমি বলব যে নীচে পোস্ট করা বিকল্পগুলির দিকে তাকানো, যে ভিবি উপায়টি এত কুৎসিত দেখাচ্ছে না।
কেভিন কারশওয়া

41
এটি নেট নেট ফ্রেমের কাজের অংশ হলে কীভাবে এটি হ্যাক হতে পারে? কোড লেখা বন্ধ করুন এবং যা পেয়েছেন তা ব্যবহার করুন।
এএমিসিকো

15
এটি একটি সাধারণ ভুল ধারণা। মাইক্রোসফ্ট.ভিউজুয়াল বেসিকতে সমস্ত সাধারণ ভিজ্যুয়াল বেসিক প্রক্রিয়া রয়েছে যা ভিবিতে কোডিংকে এত সহজ করে তোলে। মাইক্রোসট.ভিজুয়ালবাসিক.সাম্যতা হ'ল ভিবি 6 উত্তরাধিকারের জন্য ব্যবহৃত সমাবেশ।
এএমিসিকো

63
মাইক্রোসফ্ট.ভিউজুয়ালবাসিক.ড্যাভিসেস.কম্পিউটার.ফাইলে সিস্টেমটিতে কোডের 2 হাজারেরও বেশি লাইন রয়েছে। কপিডাইরেক্টরি নিশ্চিত করে যে আপনি কোনও পিতা-মাতা ফোল্ডারটি চাইল্ড ফোল্ডারে এবং অন্যান্য চেকগুলিতে অনুলিপি করছেন না। এটি অত্যন্ত অনুকূল, এবং আরও অনেক কিছু and নির্বাচিত উত্তরটি সবচেয়ে ভঙ্গুর কোড।
এএমিসিকো

17
@ এমিসিকো - ঠিক আছে, তবে কেন এই অনুকূলিত এবং সম্পূর্ণ কোডটি না Microsoft.VisualBasicএবং নেই System.IO? মনোতে না থাকার কারণ হ'ল যে সমস্ত গ্রন্থাগারগুলি 'কোর' হিসাবে বিবেচিত হয় সেগুলি হ'ল System.[something]- অন্য সমস্তগুলি নেই। অতিরিক্ত ডিএলএল উল্লেখ করতে আমার কোনও সমস্যা হয়নি, তবে মাইক্রোসফ্ট এই বৈশিষ্ট্যটি অন্তর্ভুক্ত না করার একটি ভাল কারণ রয়েছে System.IO
কিথ

উত্তর:


553

আরো সহজ

//Now Create all of the directories
foreach (string dirPath in Directory.GetDirectories(SourcePath, "*", 
    SearchOption.AllDirectories))
    Directory.CreateDirectory(dirPath.Replace(SourcePath, DestinationPath));

//Copy all the files & Replaces any files with the same name
foreach (string newPath in Directory.GetFiles(SourcePath, "*.*", 
    SearchOption.AllDirectories))
    File.Copy(newPath, newPath.Replace(SourcePath, DestinationPath), true);

25
এটি প্রকৃতপক্ষে কোডের একটি দুর্দান্ত অংশ তবে এটি কোনও ধরণের কোড নয় যা কোথাও ব্যবহার করা যেতে পারে। বিকাশকারীদের সাবধান হওয়া উচিত কারণ dirPath. প্রতিস্থাপনের ফলে অযাচিত ফলাফল হতে পারে। লোকেদের জন্য কেবল একটি সতর্কতা যা নেটকে অনুলিপি এবং পেস্ট করা পছন্দ করে। @Jaysponsored পোস্ট করা কোডটি নিরাপদ কারণ এটি স্ট্রিং ব্যবহার করে না ep প্রতিস্থাপন তবে আমি নিশ্চিত যে এটির কোণার কেসগুলিও রয়েছে।
অ্যালেক্স

17
এই কোডটি সম্পর্কে সতর্ক হন কারণ এটি লক্ষ্যবস্তু ডিরেক্টরি ইতিমধ্যে উপস্থিত থাকলে একটি ব্যতিক্রম ছুঁড়ে দেবে। এটি ইতিমধ্যে বিদ্যমান ফাইলগুলি ওভাররাইটও করবে না। প্রতিটি ডিরেক্টরি তৈরি করার আগে কেবল একটি চেক যুক্ত করুন এবং যদি উপস্থিত থাকে তবে লক্ষ্য ফাইলটি ওভাররাইট করতে ফাইল.কপি এর ওভারলোড ব্যবহার করুন।
জয়েরেজ

30
@ সাইসফট - Replaceআপনার যদি পথের ভিতরে পুনরাবৃত্তি করার ধরণ থাকে তবে একটি সমস্যা রয়েছে, উদাহরণস্বরূপ "sourceDir/things/sourceDir/things"হওয়া উচিত "destinationDir/things/sourceDir/things", তবে আপনি যদি এটি প্রতিস্থাপন করেন তবে তা হয়ে যায়"destinationDir/things/destinationDir/things"
কিথ

35
এর *.*বদলে কেন *? আপনি কি এক্সটেনশন ছাড়াই ফাইলগুলি অনুলিপি করতে চান না?
ড্যারিল

10
আসুন কিছু বানাতে এবং ওপেন সোর্স এটাকে অবদান রাখি। নেট কোর ...: /
Mzn

231

হুম, আমি মনে করি আমি প্রশ্নটি ভুল বুঝেছি তবে আমি এটি ঝুঁকি নিয়ে যাচ্ছি। নিম্নলিখিত সোজা পদ্ধতিতে কী ভুল?

public static void CopyFilesRecursively(DirectoryInfo source, DirectoryInfo target) {
    foreach (DirectoryInfo dir in source.GetDirectories())
        CopyFilesRecursively(dir, target.CreateSubdirectory(dir.Name));
    foreach (FileInfo file in source.GetFiles())
        file.CopyTo(Path.Combine(target.FullName, file.Name));
}

সম্পাদনা করুন যেহেতু এই পোস্টিংটি একটি সমান সরল প্রশ্নের উত্তরের জন্য একটি চিত্তাকর্ষক সংখ্যক ডাউনভোট সংগ্রহ করেছে, তাই আমি একটি ব্যাখ্যা যুক্ত করি। দয়া করে downvoting আগে এই পড়া

প্রথমত, এই কোডটি প্রশ্নের কোডটিতে একটি ড্রপ-ইন প্রতিস্থাপন হিসাবে উদ্দেশ্য নয়। এটি কেবল উদাহরণের উদ্দেশ্যে।

Microsoft.VisualBasic.Devices.Computer.FileSystem.CopyDirectoryকিছু অতিরিক্ত নির্ভুলতা পরীক্ষা করে (যেমন উত্স এবং লক্ষ্যটি বৈধ ডিরেক্টরি কিনা, উত্সটি লক্ষ্যটির পিতামাতা কিনা that) যা এই উত্তরটি থেকে অনুপস্থিত। এই কোডটি সম্ভবত আরও অনুকূলিত।

বলেছিল, কোডটি ভাল কাজ করে । এটা আছে (প্রায় অভিন্নরুপে) বছর ধরে একটি পরিপক্ক সফ্টওয়্যার ব্যবহার করা। সমস্ত আইও হ্যান্ডলিং সহ অন্তর্নিহিত চঞ্চলতা ছাড়াও (উদাহরণস্বরূপ, যদি আপনার কোডটি লেখার সময় ব্যবহারকারী ম্যানুয়ালি ইউএসবি ড্রাইভটি আনপ্লাগ করেন তবে কী ঘটে?), কোনও সমস্যা নেই are

বিশেষত, আমি এটি উল্লেখ করতে চাই যে এখানে পুনরাবৃত্তির ব্যবহার একেবারেই সমস্যা নয়। তত্ত্বের মধ্যে না (ধারণাগতভাবে, এটি সর্বাধিক মার্জিত সমাধান) বা বাস্তবে নয় : এই কোডটি স্ট্যাকটিকে উপচে ফেলবে না । স্ট্যাকটি যথেষ্ট গভীরভাবে নেস্টেড ফাইলের স্তরক্রমগুলি পরিচালনা করতে যথেষ্ট বড়। স্ট্যাক স্পেস কোনও সমস্যায় পরিণত হওয়ার অনেক আগে, ফোল্ডারের পথ দৈর্ঘ্যের সীমাবদ্ধতাটি কিক।

লক্ষ্য করুন যে কোনও দূষিত ব্যবহারকারী প্রতিটি অক্ষরের গভীর-নেস্টযুক্ত ডিরেক্টরি ব্যবহার করে এই ধারণাটি ভাঙ্গতে সক্ষম হতে পারেন। আমি এটি চেষ্টা করিনি। তবে কেবলমাত্র পয়েন্টটি বর্ণনা করার জন্য: একটি সাধারণ কম্পিউটারে এই কোডটি ওভারফ্লো করতে, ডিরেক্টরিগুলি কয়েক হাজার বার নেস্ট করাতে হবে । এটি কেবল বাস্তবের দৃশ্য নয় not


5
এটি প্রধান পুনরাবৃত্তি। ডিরেক্টরিগুলি গভীরভাবে নিস্ট করা থাকলে এটি একটি স্ট্যাক ওভারফ্লোয়ের শিকার হতে পারে।
স্পোলসন

19
খুব সম্প্রতি অবধি, ডিরেক্টরি নীড়ের গভীরতা ওএস দ্বারা সীমাবদ্ধ ছিল। আমি সন্দেহ করি যে আপনি এমন ডিরেক্টরিগুলি খুঁজে পাবেন যা কয়েকশবারেরও বেশি সময় বাসাযুক্ত (যদি এমনকি)। উপরের কোডটি আরও অনেক বেশি নিতে পারে ।
কনরাড রুডলফ

5
আমি পুনরাবৃত্তির পদ্ধতির মতো, স্ট্যাকের ওভারফ্লোর ঝুঁকি সর্বনিম্নতম।
ডেভিড বাসরব

49
@ ডিটিশকিনোভ: আমাকে ক্ষমা করে দিন তবে এটাকে খুব বাজে মনে হচ্ছে। স্পষ্ট কোড == ডাউনভোট কেন? বিপরীতটি সত্য হওয়া উচিত। অন্তর্নির্মিত পদ্ধতিটি ইতিমধ্যে পোস্ট করা হয়েছিল তবে কীথ বিশেষভাবে অন্য পদ্ধতির জন্য জিজ্ঞাসা করেছিল । এছাড়াও, আপনার শেষ বাক্যটি দ্বারা আপনি কী বোঝাতে চাইছেন? দুঃখিত, তবে আমি আপনার মোটামুটি ডাউনভোটিংয়ের কারণগুলি বুঝতে পারি না।
কনরাড রুডল্ফ

6
@ এমিসিকো: এর চেয়ে ভাল কি ? ফ্রেমওয়ার্ক থেকে এটি কোনও ভিবি কোডের চেয়ে ভাল বলে দাবি করেননি কেউ। আমরা জানি এটা না।
কনরাড রুডল্ফ

131

এমএসডিএন থেকে অনুলিপি করা :

using System;
using System.IO;

class CopyDir
{
    public static void Copy(string sourceDirectory, string targetDirectory)
    {
        DirectoryInfo diSource = new DirectoryInfo(sourceDirectory);
        DirectoryInfo diTarget = new DirectoryInfo(targetDirectory);

        CopyAll(diSource, diTarget);
    }

    public static void CopyAll(DirectoryInfo source, DirectoryInfo target)
    {
        Directory.CreateDirectory(target.FullName);

        // Copy each file into the new directory.
        foreach (FileInfo fi in source.GetFiles())
        {
            Console.WriteLine(@"Copying {0}\{1}", target.FullName, fi.Name);
            fi.CopyTo(Path.Combine(target.FullName, fi.Name), true);
        }

        // Copy each subdirectory using recursion.
        foreach (DirectoryInfo diSourceSubDir in source.GetDirectories())
        {
            DirectoryInfo nextTargetSubDir =
                target.CreateSubdirectory(diSourceSubDir.Name);
            CopyAll(diSourceSubDir, nextTargetSubDir);
        }
    }

    public static void Main()
    {
        string sourceDirectory = @"c:\sourceDirectory";
        string targetDirectory = @"c:\targetDirectory";

        Copy(sourceDirectory, targetDirectory);
    }

    // Output will vary based on the contents of the source directory.
}

8
ডিরেক্টরি উপস্থিত আছে কিনা তা পরীক্ষা করার কোনও কারণ নেই, কেবল ডাইরেক্টটিকে ডেকে দিন। ক্রিয়েট ডিরেক্টরী যা ডিরেক্টরি ইতিমধ্যে উপস্থিত থাকলে কিছুই করবে না।
তাল জেরোমে

1
256 টির চেয়ে বেশি অক্ষরের চেয়ে বেশি পাথগুলি মোকাবেলা করার জন্য, আপনি জেটলংপ্যাথস নামে একটি নুগেট প্যাকেজ ব্যবহার করতে পারেন
একে

2
এই উত্তরটি তাদের সকলের মধ্যে সবচেয়ে কার্যকর বলে মনে হচ্ছে। স্ট্রিংয়ের পরিবর্তে ডিরেক্টরীআইএনফো ব্যবহার করে প্রচুর সম্ভাব্য সমস্যা এড়ানো যায়।
দাইদালুস

50

এটা চেষ্টা কর:

Process proc = new Process();
proc.StartInfo.UseShellExecute = true;
proc.StartInfo.FileName = Path.Combine(Environment.SystemDirectory, "xcopy.exe");
proc.StartInfo.Arguments = @"C:\source C:\destination /E /I";
proc.Start();

আপনার এক্সকপি যুক্তিগুলি ভিন্ন হতে পারে তবে আপনি ধারণা পাবেন।


3
/ ই এটি সমস্ত উপ ডিরেক্টরি (এমনকি খালিও) অনুলিপি করতে বলে। / আমি এটিকে বলি যে গন্তব্য উপস্থিত না থাকলে সেই নামের সাথে একটি ডিরেক্টরি তৈরি করুন।
d4nt

6
নিরাপদ থাকতে ডাবল উদ্ধৃতি যুক্ত করুন।
জায়সোনরাগসা

6
বিদ্যমান ফাইলগুলি ওভাররাইট করতে অনুরোধ জানাতে / যোগ করুন। stackoverflow.com/q/191209/138938
জন ক্রোয়েল

16
দুঃখিত, তবে এটি ভয়াবহ। এটি ধরে নিয়েছে যে টার্গেট সিস্টেমটি উইন্ডোজ। এটি ধরে নেওয়া হয়েছে যে ভবিষ্যতের সংস্করণগুলিতে সেই নির্দিষ্ট পথে xcopy.exe অন্তর্ভুক্ত রয়েছে। এটি ধরে নিয়েছে যে এক্সকপির প্যারামিটারগুলি পরিবর্তন হয় না। এটির জন্য xcopy এর প্যারামিটারগুলি স্ট্রিং হিসাবে একত্রিত করা দরকার যা প্রচুর ত্রুটির সম্ভাবনা প্রবর্তন করে। এছাড়াও নমুনাটি শুরু হওয়া প্রক্রিয়ার ফলাফলগুলির জন্য কোনও ত্রুটি পরিচালনার কথা উল্লেখ করে না, যা আমি আশা করব, কারণ অন্যান্য পদ্ধতির বিপরীতে এটি নিঃশব্দে ব্যর্থ হবে fail
সেল তীক্ষ্ণ

3
@ মাথিয়াস জানসেন, আমি মনে করি আপনি এটি খুব ব্যক্তিগতভাবে নিয়েছেন। উত্তরটি বিন্দুতে রয়েছে এবং এটি কীভাবে অর্জন করা যায় সে সম্পর্কে অনেকগুলি ব্যাখ্যা করে ... যেহেতু প্রশ্নটি ক্রস প্ল্যাটফর্মের সামঞ্জস্যতা বা এক্সকপি বা অন্য কিছু ব্যবহার না করার দাবি করে না, কেবল কীভাবে এটি একভাবে অর্জন করা যায় তা ব্যাখ্যা করার জন্য পোস্টার কেবল উত্তর দিয়েছে ... সেখানে একই জিনিস করার 1000 টি উপায় হতে পারে এবং উত্তরগুলি পৃথক হতে পারে that's এজন্য এই ফোরামটি এখানে বিশ্বব্যাপী সম্বোধন করার জন্য এবং প্রোগ্রামাররা তাদের অভিজ্ঞতা ভাগ করে নিতে এখানে এসেছেন। আমি আপনার মন্তব্য ভোট।
কেএমএক্স

47

অথবা, আপনি যদি শক্ত পথে যেতে চান তবে মাইক্রোসফ্টের জন্য আপনার প্রকল্পের জন্য একটি রেফারেন্স যুক্ত করুন is ভিজুয়ালবাসিক এবং তারপরে নিম্নলিখিতটি ব্যবহার করুন:

Microsoft.VisualBasic.FileIO.FileSystem.CopyDirectory(fromDirectory, toDirectory);

যাইহোক, পুনরাবৃত্ত ফাংশনগুলির একটি ব্যবহার করা আরও ভাল উপায় যেহেতু এটিতে ভিবি dll লোড করতে হবে না।


1
যাইহোক আমি এটি কীভাবে করেছি তার থেকে এটি সত্যিই আলাদা নয় - এটি করতে সক্ষম হওয়ার জন্য আপনার এখনও ভিবি'র পশ্চাদপদ-সামঞ্জস্যতা স্টাফ লোড করতে হবে।
কিথ

10
ভিবি অ্যাসেম্বলি লোড করা কি ব্যয়বহুল? ভিবি বিকল্পগুলি সি # সংস্করণের তুলনায় অনেক বেশি মার্জিত।
jwmiller5

3
"ভিবি'র পিছনে-সামঞ্জস্যের জিনিসগুলি কী? কপিরডিটারিরি শেল বা ফ্রেমওয়ার্ক ব্যবহার করে।
এএমিসিকো

3
আমার ইচ্ছা যদি এটি চালু থাকে System.IO.Directoryতবে এটি আবার লেখার চেয়ে ভাল!
জোশ এম

2
এটি
ইমোতে

38

এই সাইটটি সর্বদা আমাকে অনেক সাহায্য করেছে এবং আমি এখন যা জানি আমার সাথে অন্যদেরও সাহায্য করার পালা।

আমি আশা করি যে নীচের আমার কোডটি কারও জন্য কার্যকর হবে।

string source_dir = @"E:\";
string destination_dir = @"C:\";

// substring is to remove destination_dir absolute path (E:\).

// Create subdirectory structure in destination    
    foreach (string dir in System.IO.Directory.GetDirectories(source_dir, "*", System.IO.SearchOption.AllDirectories))
    {
        System.IO.Directory.CreateDirectory(System.IO.Path.Combine(destination_dir, dir.Substring(source_dir.Length + 1)));
        // Example:
        //     > C:\sources (and not C:\E:\sources)
    }

    foreach (string file_name in System.IO.Directory.GetFiles(source_dir, "*", System.IO.SearchOption.AllDirectories))
    {
        System.IO.File.Copy(file_name, System.IO.Path.Combine(destination_dir, file_name.Substring(source_dir.Length + 1)));
    }

1
পিছনের ব্যাকস্ল্যাশ সম্পর্কে মনে রাখবেন
আলেক্সি এফ

24
ভাবেন, ব্যবহার করুন Path.Combine()। একসাথে ফাইল পাথ রাখতে স্ট্রিং কনটেনটেশন ব্যবহার করবেন না।
অ্যান্ডি

3
উপরের কোড স্নিপেটে আপনার একটি ওবিওবি আছে। আপনি ব্যবহার করা উচিত source_dir.Length + 1, না source_dir.Length
পেলুসিডওম্ব্যাট

এই কোডটি একটি ভাল ধারণা, কিন্তু ... একটি ফাইলের "থাকা উচিত নয়।" এতে, তাই ystem.IO.Directory.GetFiles (উত্স_ডির, "*", সিস্টেম.আইও.সন্ধান অপশন.অলডাইরেক্টরিস) ব্যবহার করা ভাল
জিন লিবেরা

আপনাকে ধন্যবাদ জিনলিবার, আপনি ঠিক বলেছেন। আমি আপনার পরামর্শ দিয়ে কোড পরিবর্তন করেছি।
জয়স্পনসর

14

স্ট্যাক ওভারফ্লো এড়াতে পুনরাবৃত্তি ছাড়াই ফোল্ডারটি পুনরাবৃত্তভাবে অনুলিপি করুন।

public static void CopyDirectory(string source, string target)
{
    var stack = new Stack<Folders>();
    stack.Push(new Folders(source, target));

    while (stack.Count > 0)
    {
        var folders = stack.Pop();
        Directory.CreateDirectory(folders.Target);
        foreach (var file in Directory.GetFiles(folders.Source, "*.*"))
        {
            File.Copy(file, Path.Combine(folders.Target, Path.GetFileName(file)));
        }

        foreach (var folder in Directory.GetDirectories(folders.Source))
        {
            stack.Push(new Folders(folder, Path.Combine(folders.Target, Path.GetFileName(folder))));
        }
    }
}

public class Folders
{
    public string Source { get; private set; }
    public string Target { get; private set; }

    public Folders(string source, string target)
    {
        Source = source;
        Target = target;
    }
}

দরকারী পুনরাবৃত্তি টেম্পলেট :)
মিন্ এনগুইন

2
পথের সীমাটি আলোকিত করার আগে স্ট্যাকটি ফুঁকানো কল্পনা করা শক্ত
এড এস

5

আমি এর মতো আইও কাজের জন্য একটি ইউটিলিটি ক্লাস ব্যবহার করেছি।

using System;
using System.Runtime.InteropServices;

namespace MyNameSpace
{
    public class ShellFileOperation
    {
        private static String StringArrayToMultiString(String[] stringArray)
        {
            String multiString = "";

            if (stringArray == null)
                return "";

            for (int i=0 ; i<stringArray.Length ; i++)
                multiString += stringArray[i] + '\0';

            multiString += '\0';

            return multiString;
        }

        public static bool Copy(string source, string dest)
        {
            return Copy(new String[] { source }, new String[] { dest });
        }

        public static bool Copy(String[] source, String[] dest)
        {
            Win32.SHFILEOPSTRUCT FileOpStruct = new Win32.SHFILEOPSTRUCT();

            FileOpStruct.hwnd = IntPtr.Zero;
            FileOpStruct.wFunc = (uint)Win32.FO_COPY;

            String multiSource = StringArrayToMultiString(source);
            String multiDest = StringArrayToMultiString(dest);
            FileOpStruct.pFrom = Marshal.StringToHGlobalUni(multiSource);
            FileOpStruct.pTo = Marshal.StringToHGlobalUni(multiDest);

            FileOpStruct.fFlags = (ushort)Win32.ShellFileOperationFlags.FOF_NOCONFIRMATION;
            FileOpStruct.lpszProgressTitle = "";
            FileOpStruct.fAnyOperationsAborted = 0;
            FileOpStruct.hNameMappings = IntPtr.Zero;

            int retval = Win32.SHFileOperation(ref FileOpStruct);

            if(retval != 0) return false;
            return true;
        }

        public static bool Move(string source, string dest)
        {
            return Move(new String[] { source }, new String[] { dest });
        }

        public static bool Delete(string file)
        {
            Win32.SHFILEOPSTRUCT FileOpStruct = new Win32.SHFILEOPSTRUCT();

            FileOpStruct.hwnd = IntPtr.Zero;
            FileOpStruct.wFunc = (uint)Win32.FO_DELETE;

            String multiSource = StringArrayToMultiString(new string[] { file });
            FileOpStruct.pFrom = Marshal.StringToHGlobalUni(multiSource);
            FileOpStruct.pTo =  IntPtr.Zero;

            FileOpStruct.fFlags = (ushort)Win32.ShellFileOperationFlags.FOF_SILENT | (ushort)Win32.ShellFileOperationFlags.FOF_NOCONFIRMATION | (ushort)Win32.ShellFileOperationFlags.FOF_NOERRORUI | (ushort)Win32.ShellFileOperationFlags.FOF_NOCONFIRMMKDIR;
            FileOpStruct.lpszProgressTitle = "";
            FileOpStruct.fAnyOperationsAborted = 0;
            FileOpStruct.hNameMappings = IntPtr.Zero;

            int retval = Win32.SHFileOperation(ref FileOpStruct);

            if(retval != 0) return false;
            return true;
        }

        public static bool Move(String[] source, String[] dest)
        {
            Win32.SHFILEOPSTRUCT FileOpStruct = new Win32.SHFILEOPSTRUCT();

            FileOpStruct.hwnd = IntPtr.Zero;
            FileOpStruct.wFunc = (uint)Win32.FO_MOVE;

            String multiSource = StringArrayToMultiString(source);
            String multiDest = StringArrayToMultiString(dest);
            FileOpStruct.pFrom = Marshal.StringToHGlobalUni(multiSource);
            FileOpStruct.pTo = Marshal.StringToHGlobalUni(multiDest);

            FileOpStruct.fFlags = (ushort)Win32.ShellFileOperationFlags.FOF_NOCONFIRMATION;
            FileOpStruct.lpszProgressTitle = "";
            FileOpStruct.fAnyOperationsAborted = 0;
            FileOpStruct.hNameMappings = IntPtr.Zero;

            int retval = Win32.SHFileOperation(ref FileOpStruct);

            if(retval != 0) return false;
            return true;
        }
    }
}

নোট করুন যে মাইক্রোসফ্ট মাইক্রোসফ্টের জন্য SHFileOperation অভ্যন্তরীণভাবে ব্যবহার করে .ভিজুয়ালবাসিক।
jrh

3

এটি পারফরম্যান্স-সচেতন নাও হতে পারে তবে আমি এটি 30 এমবি ফোল্ডারের জন্য ব্যবহার করছি এবং এটি নির্দোষভাবে কাজ করে। এছাড়াও, এত সহজ কাজের জন্য প্রয়োজনীয় সমস্ত পরিমাণ কোড এবং পুনরাবৃত্তি আমার পছন্দ হয়নি didn't

var source_folder = "c:\src";
var dest_folder = "c:\dest";
var zipFile = source_folder + ".zip";

ZipFile.CreateFromDirectory(source_folder, zipFile);
ZipFile.ExtractToDirectory(zipFile, dest_folder);
File.Delete(zipFile);

দ্রষ্টব্য: জিপফাইলে সিস্টেম.আইও.কম্প্রেশন নেমস্পেসে .NET 4.5+ এ উপলব্ধ


1
আমি না, তাই প্রশ্ন করি না, তবে নির্বাচিত উত্তরের পুনরাবৃত্তি দরকার হয় না। এই উত্তরটি ডিস্কে একটি জিপ ফাইল তৈরি করে, যা একটি ফাইল অনুলিপির জন্য অতিরিক্ত কাজ - কেবলমাত্র আপনি ডেটার অতিরিক্ত কপি তৈরি করছেন না, তবে আপনি প্রসেসরের সময় এটি সংকুচিত এবং সংক্ষেপিত করতে ব্যয় করছেন। আমি নিশ্চিত যে এটি কাজ করে, একইভাবে আপনি সম্ভবত আপনার জুতো দিয়ে পেরেক ঠোকরতে পারেন, তবে এটি আরও বেশি কাজ করে যা ভুল হতে পারে, যদিও এটি করার আরও ভাল উপায় রয়েছে।
কিথ

আমি এর সাথে শেষ হওয়ার কারণটি হ'ল স্ট্রিং প্রতিস্থাপন। অন্যরা যেমন উল্লেখ করেছে, স্বীকৃত উত্তরটি অনেক উদ্বেগকে উপস্থাপন করে; জংশন লিঙ্কটি কাজ না করতে পারে, পাশাপাশি ফোল্ডার প্যাটার্ন বা ফাইলগুলি এক্সটেনশন বা নাম ছাড়াই পুনরাবৃত্তি করতে পারে। কোড কম, ভুল হওয়ার কম সুযোগ। এবং যেহেতু প্রসেসরের সময়টি আমার পক্ষে উদ্বেগের বিষয় নয়, এটি এটি আমার নির্দিষ্ট মামলার জন্য উপযুক্ত করে তোলে
আলেকজান্ডারডি

2
হ্যাঁ, এটি কোনও ট্র্যাফিক আলো এড়াতে আপনার পথ থেকে 1000 মাইল দূরে সরে যাওয়ার মতো, তবে এটি আপনার যাত্রা, তাই এটির জন্য যান। ফোল্ডারের নিদর্শনগুলির জন্য চেক করা হুডের নীচে জিপ করার দরকারের তুলনায় তুচ্ছ। আমি প্রসেসর, ডিস্ক, বিদ্যুৎ নষ্ট না করা বা যেখানে একই মেশিনে অন্যান্য প্রোগ্রামের পাশাপাশি এটি চালানো প্রয়োজন সেখানে যে কেউ যত্নশীল তা জন্য আমি এর বিরুদ্ধে দৃ strongly়তার সাথে সুপারিশ করব। এছাড়াও, যদি আপনি কখনও সাক্ষাত্কারে এই ধরণের প্রশ্ন জিজ্ঞাসা করেন না তবে "আমার কোডটি সহজ তাই আমি প্রসেসরের সময় সম্পর্কে চিন্তা করি না" - আপনি চাকরি পাবেন না।
কিথ

1
@ জাস্টিন-আর দ্বারা প্রদত্ত উত্তরে আমি স্যুইচ করেছি । তবুও, আমি এই উত্তরটি এটি করার অন্য একটি উপায় হিসাবে রেখে দেব
আলেকজান্ডারডি

1
যদি ফোল্ডারগুলি পৃথক নেটওয়ার্ক শেয়ারে থাকে এবং প্রচুর ফাইল থাকে তবে এটি আমার মতে সেরা বিকল্প হবে।
ড্যানি পার্কার

2

D4nt- এর উত্তরে একটি সামান্য উন্নতি, কারণ আপনি সম্ভবত ত্রুটিগুলি পরীক্ষা করতে চান এবং আপনি যদি সার্ভার এবং ডেভেলপমেন্ট মেশিনে কাজ করছেন তবে এক্সকপি পাথগুলি পরিবর্তন করতে হবে না:

public void CopyFolder(string source, string destination)
{
    string xcopyPath = Environment.GetEnvironmentVariable("WINDIR") + @"\System32\xcopy.exe";
    ProcessStartInfo info = new ProcessStartInfo(xcopyPath);
    info.UseShellExecute = false;
    info.RedirectStandardOutput = true;
    info.Arguments = string.Format("\"{0}\" \"{1}\" /E /I", source, destination);

    Process process = Process.Start(info);
    process.WaitForExit();
    string result = process.StandardOutput.ReadToEnd();

    if (process.ExitCode != 0)
    {
        // Or your own custom exception, or just return false if you prefer.
        throw new InvalidOperationException(string.Format("Failed to copy {0} to {1}: {2}", source, destination, result));
    }
}

2

এটি আমার কোডটি আশা করি এই সহায়তা

    private void KCOPY(string source, string destination)
    {
        if (IsFile(source))
        {
            string target = Path.Combine(destination, Path.GetFileName(source));
            File.Copy(source, target, true);
        }
        else
        {
            string fileName = Path.GetFileName(source);
            string target = System.IO.Path.Combine(destination, fileName);
            if (!System.IO.Directory.Exists(target))
            {
                System.IO.Directory.CreateDirectory(target);
            }

            List<string> files = GetAllFileAndFolder(source);

            foreach (string file in files)
            {
                KCOPY(file, target);
            }
        }
    }

    private List<string> GetAllFileAndFolder(string path)
    {
        List<string> allFile = new List<string>();
        foreach (string dir in Directory.GetDirectories(path))
        {
            allFile.Add(dir);
        }
        foreach (string file in Directory.GetFiles(path))
        {
            allFile.Add(file);
        }

        return allFile;
    }
    private bool IsFile(string path)
    {
        if ((File.GetAttributes(path) & FileAttributes.Directory) == FileAttributes.Directory)
        {
            return false;
        }
        return true;
    }

SearchOptionফোল্ডার এবং ফাইলগুলির সন্ধানে পতাকা ব্যবহার করে নির্বাচিত উত্তরটি দেখুন এটি কোডের 4 লাইনে এটি করে। এছাড়াও চেক আউট .HasFlagএক্সটেনশন এখন enums উপর।
কিথ

2

আপনি যদি কনরাডের জনপ্রিয় উত্তরটি পছন্দ করেন তবে আপনি চান তার সন্তানদের sourceফোল্ডারের নিচে targetরাখার পরিবর্তে নিজেই একটি ফোল্ডার হ'ল সেটির targetকোডটি এখানে। এটি সদ্য নির্মিত DirectoryInfo, যা কার্যকর:

public static DirectoryInfo CopyFilesRecursively(DirectoryInfo source, DirectoryInfo target)
{
  var newDirectoryInfo = target.CreateSubdirectory(source.Name);
  foreach (var fileInfo in source.GetFiles())
    fileInfo.CopyTo(Path.Combine(newDirectoryInfo.FullName, fileInfo.Name));

  foreach (var childDirectoryInfo in source.GetDirectories())
    CopyFilesRecursively(childDirectoryInfo, newDirectoryInfo);

  return newDirectoryInfo;
}

2

আপনি সর্বদা ব্যবহার করতে পারেন এই , Microsofts ওয়েবসাইট থেকে নেওয়া।

static void Main()
{
    // Copy from the current directory, include subdirectories.
    DirectoryCopy(".", @".\temp", true);
}

private static void DirectoryCopy(string sourceDirName, string destDirName, bool copySubDirs)
{
    // Get the subdirectories for the specified directory.
    DirectoryInfo dir = new DirectoryInfo(sourceDirName);

    if (!dir.Exists)
    {
        throw new DirectoryNotFoundException(
            "Source directory does not exist or could not be found: "
            + sourceDirName);
    }

    DirectoryInfo[] dirs = dir.GetDirectories();
    // If the destination directory doesn't exist, create it.
    if (!Directory.Exists(destDirName))
    {
        Directory.CreateDirectory(destDirName);
    }

    // Get the files in the directory and copy them to the new location.
    FileInfo[] files = dir.GetFiles();
    foreach (FileInfo file in files)
    {
        string temppath = Path.Combine(destDirName, file.Name);
        file.CopyTo(temppath, false);
    }

    // If copying subdirectories, copy them and their contents to new location.
    if (copySubDirs)
    {
        foreach (DirectoryInfo subdir in dirs)
        {
            string temppath = Path.Combine(destDirName, subdir.Name);
            DirectoryCopy(subdir.FullName, temppath, copySubDirs);
        }
    }
}

1
এটি দুর্দান্ত - লাইন file.CopyTo(temppath, false);মনে রাখবেন "এই জায়গায় এই ফাইলটি অনুলিপি করুন, কেবল যদি এটি বিদ্যমান না থাকে", যা বেশিরভাগ সময় আমরা চাই না isn't তবে, আমি বুঝতে পারি যে এটি কেন ডিফল্ট হয়। ফাইলগুলিকে ওভাররাইট করার জন্য পদ্ধতিটিতে একটি পতাকা যুক্ত করতে পারে।
অ্যান্ডি

2

tboswell এর প্রুফ সংস্করণ প্রতিস্থাপন (যা ফাইলপথে পুনরাবৃত্তি প্যাটার্নের জন্য স্থিতিস্থাপক)

public static void copyAll(string SourcePath , string DestinationPath )
{
   //Now Create all of the directories
   foreach (string dirPath in Directory.GetDirectories(SourcePath, "*", SearchOption.AllDirectories))
      Directory.CreateDirectory(Path.Combine(DestinationPath ,dirPath.Remove(0, SourcePath.Length ))  );

   //Copy all the files & Replaces any files with the same name
   foreach (string newPath in Directory.GetFiles(SourcePath, "*.*",  SearchOption.AllDirectories))
      File.Copy(newPath, Path.Combine(DestinationPath , newPath.Remove(0, SourcePath.Length)) , true);
    }

3
ভাবেন, ব্যবহার করুন Path.Combine()। একসাথে ফাইল পাথ রাখতে স্ট্রিং কনটেনটেশন ব্যবহার করবেন না।
অ্যান্ডি

2

আমার সমাধানটি মূলত @ টার্মিনঞ্জার উত্তরের একটি পরিবর্তন, তবে আমি এটি কিছুটা বাড়িয়েছি এবং এটি গৃহীত উত্তরের চেয়ে 5 গুণ বেশি দ্রুত বলে মনে হচ্ছে।

public static void CopyEntireDirectory(string path, string newPath)
{
    Parallel.ForEach(Directory.GetFileSystemEntries(path, "*", SearchOption.AllDirectories)
    ,(fileName) =>
    {
        string output = Regex.Replace(fileName, "^" + Regex.Escape(path), newPath);
        if (File.Exists(fileName))
        {
            Directory.CreateDirectory(Path.GetDirectoryName(output));
            File.Copy(fileName, output, true);
        }
        else
            Directory.CreateDirectory(output);
    });
}

সম্পাদনা: @ আহমদ সাব্রিকে সম্পূর্ণ সমান্তরাল পূর্বাঞ্চে পরিবর্তন করা আরও ভাল ফলাফলের ফলাফল করে, তবে কোডটি পুনরাবৃত্ত ফাংশন ব্যবহার করে এবং এটি কিছু পরিস্থিতিতে আদর্শ নয়।

public static void CopyEntireDirectory(DirectoryInfo source, DirectoryInfo target, bool overwiteFiles = true)
{
    if (!source.Exists) return;
    if (!target.Exists) target.Create();

    Parallel.ForEach(source.GetDirectories(), (sourceChildDirectory) =>
        CopyEntireDirectory(sourceChildDirectory, new DirectoryInfo(Path.Combine(target.FullName, sourceChildDirectory.Name))));

    Parallel.ForEach(source.GetFiles(), sourceFile =>
        sourceFile.CopyTo(Path.Combine(target.FullName, sourceFile.Name), overwiteFiles));
}

1

পূর্ববর্তী কোডটির জন্য দুঃখিত, এটিতে ত্রুটিগুলি ছিল :( (দ্রুততম বন্দুক সমস্যার শিকার হয়ে পড়েছিল) Hereএটি এটি পরীক্ষা করা এবং কাজ করা হয়েছে key

string path = "C:\\a";
string[] dirs = Directory.GetDirectories(path, "*.*", SearchOption.AllDirectories);
string newpath = "C:\\x";
try
{
    Directory.CreateDirectory(newpath);
}
catch (IOException ex)
{
    Console.WriteLine(ex.Message);
}
for (int j = 0; j < dirs.Length; j++)
{
    try
    {
        Directory.CreateDirectory(dirs[j].Replace(path, newpath));
    }
    catch (IOException ex)
    {
        Console.WriteLine(ex.Message);
    }
}

string[] files = Directory.GetFiles(path, "*.*", SearchOption.AllDirectories);
for (int j = 0; j < files.Length; j++)            
{
    try
    {
        File.Copy(files[j], files[j].Replace(path, newpath));
    }
    catch (IOException ex)
    {
        Console.WriteLine(ex.Message);
    }
}

1

ডিরেক্টরীআইএনফো একটি লা ফাইলআইএনফো-কপিটিও ( overwriteপ্যারামিটারটি নোট করুন ) এর জন্য এখানে একটি বর্ধিত পদ্ধতি রয়েছে :

public static DirectoryInfo CopyTo(this DirectoryInfo sourceDir, string destinationPath, bool overwrite = false)
{
    var sourcePath = sourceDir.FullName;

    var destination = new DirectoryInfo(destinationPath);

    destination.Create();

    foreach (var sourceSubDirPath in Directory.EnumerateDirectories(sourcePath, "*", SearchOption.AllDirectories))
        Directory.CreateDirectory(sourceSubDirPath.Replace(sourcePath, destinationPath));

    foreach (var file in Directory.EnumerateFiles(sourcePath, "*", SearchOption.AllDirectories))
        File.Copy(file, file.Replace(sourcePath, destinationPath), overwrite);

    return destination;
}

1

এই ক্লাস ব্যবহার করুন।

public static class Extensions
{
    public static void CopyTo(this DirectoryInfo source, DirectoryInfo target, bool overwiteFiles = true)
    {
        if (!source.Exists) return;
        if (!target.Exists) target.Create();

        Parallel.ForEach(source.GetDirectories(), (sourceChildDirectory) => 
            CopyTo(sourceChildDirectory, new DirectoryInfo(Path.Combine(target.FullName, sourceChildDirectory.Name))));

        foreach (var sourceFile in source.GetFiles())
            sourceFile.CopyTo(Path.Combine(target.FullName, sourceFile.Name), overwiteFiles);
    }
    public static void CopyTo(this DirectoryInfo source, string target, bool overwiteFiles = true)
    {
        CopyTo(source, new DirectoryInfo(target), overwiteFiles);
    }
}

1
এটি অন্যান্য উত্তরের মতো, ব্যবহারের জন্য রিফ্যাক্টর .ToList().ForEach((যা সরাসরি ডিরেক্টরিগুলি গণনা করার চেয়ে কিছুটা বেশি কাজ, মেমরি এবং সামান্য ধীর) এবং এক্সটেনশন পদ্ধতি হিসাবে। নির্বাচিত উত্তর SearchOption.AllDirectoriesপুনরাবৃত্তিটি ব্যবহার করে এবং এড়ায়, তাই আমি সেই মডেলটিতে স্যুইচ করার পরামর্শ দিই। এছাড়াও, আপনার সাধারণত প্রসারণ পদ্ধতির টাইপের নামটির প্রয়োজন হয় না - আমি এটির নামকরণ করে রাখি CopyTo()যাতে এটি হয়ে যায়sourceDir.CopyTo(destination);
কিথ

1

সমস্ত ফোল্ডার এবং ফাইলের অনুলিপি করার জন্য কেবল একটি লুপ সহ একটি বৈকল্পিক:

foreach (var f in Directory.GetFileSystemEntries(path, "*", SearchOption.AllDirectories))
{
    var output = Regex.Replace(f, @"^" + path, newPath);
    if (File.Exists(f)) File.Copy(f, output, true);
    else Directory.CreateDirectory(output);
}

আপনি যদি ব্যবহার করতে চলেছেন তবে আপনার এক্সপ্রেশন রচনাটির অংশ Regexহিসাবেও সম্ভবত হওয়া উচিত Regex.Escape(path)(বিশেষত উইন্ডোজ পাথ বিভাজক বিবেচনা করে)। আপনি স্থির পদ্ধতিতে নির্ভর না করে লুপের বাইরে কোনও বস্তু তৈরি (এবং সম্ভবত সংকলন) করেও উপকার পেতে পারেনnew Regex()
jimbobmcgee

0

যে কোনও কোডের চেয়ে ভাল (পুনরাবৃত্তির সাথে ডিরেক্টরীআইএনফোতে এক্সটেনশন পদ্ধতি)

public static bool CopyTo(this DirectoryInfo source, string destination)
    {
        try
        {
            foreach (string dirPath in Directory.GetDirectories(source.FullName))
            {
                var newDirPath = dirPath.Replace(source.FullName, destination);
                Directory.CreateDirectory(newDirPath);
                new DirectoryInfo(dirPath).CopyTo(newDirPath);
            }
            //Copy all the files & Replaces any files with the same name
            foreach (string filePath in Directory.GetFiles(source.FullName))
            {
                File.Copy(filePath, filePath.Replace(source.FullName,destination), true);
            }
            return true;
        }
        catch (IOException exp)
        {
            return false;
        }
    }

1
আমি নিশ্চিত নই যে এটি পুনরাবৃত্তি (যেখানে এটির দরকার নেই) ব্যবহার করা এবং ডিবাগিংকে আরও শক্ত করে তুলতে ব্যতিক্রমগুলি গোপন করা ব্যতীত গ্রহণযোগ্য উত্তরের চেয়ে কী যুক্ত করে।
কিথ

0

ফোল্ডারের সমস্ত ফাইল অনুলিপি করুন এবং প্রতিস্থাপন করুন

        public static void CopyAndReplaceAll(string SourcePath, string DestinationPath, string backupPath)
    {
            foreach (string dirPath in Directory.GetDirectories(SourcePath, "*", SearchOption.AllDirectories))
            {
                Directory.CreateDirectory($"{DestinationPath}{dirPath.Remove(0, SourcePath.Length)}");
                Directory.CreateDirectory($"{backupPath}{dirPath.Remove(0, SourcePath.Length)}");
            }
            foreach (string newPath in Directory.GetFiles(SourcePath, "*.*", SearchOption.AllDirectories))
            {
                if (!File.Exists($"{ DestinationPath}{newPath.Remove(0, SourcePath.Length)}"))
                    File.Copy(newPath, $"{ DestinationPath}{newPath.Remove(0, SourcePath.Length)}");
                else
                    File.Replace(newPath
                        , $"{ DestinationPath}{newPath.Remove(0, SourcePath.Length)}"
                        , $"{ backupPath}{newPath.Remove(0, SourcePath.Length)}", false);
            }
    }

উত্তরের জন্য চিয়ারস, তবে আমি নিশ্চিত নই যে এটি কী যুক্ত করে। এছাড়াও try catch throwঅর্থহীন।
কীথ

0

নিচের কোড মাইক্রোসফট পরামর্শ কিভাবে-থেকে-কপি-ডিরেক্টরি এবং এটি দুর্মূল্য দ্বারা ভাগ করা @iato কিন্তু এটি শুধু কপি সাব ডিরেক্টরি এবং যাও recursively উৎস ফোল্ডার ফাইল এবং এটি স্ব ফোল্ডারের উৎস কপি নেই (ডান ক্লিক মত -> কপি )।

তবে এই উত্তরের নীচে একটি কৌশল আছে :

private static void DirectoryCopy(string sourceDirName, string destDirName, bool copySubDirs = true)
        {
            // Get the subdirectories for the specified directory.
            DirectoryInfo dir = new DirectoryInfo(sourceDirName);

            if (!dir.Exists)
            {
                throw new DirectoryNotFoundException(
                    "Source directory does not exist or could not be found: "
                    + sourceDirName);
            }

            DirectoryInfo[] dirs = dir.GetDirectories();
            // If the destination directory doesn't exist, create it.
            if (!Directory.Exists(destDirName))
            {
                Directory.CreateDirectory(destDirName);
            }

            // Get the files in the directory and copy them to the new location.
            FileInfo[] files = dir.GetFiles();
            foreach (FileInfo file in files)
            {
                string temppath = Path.Combine(destDirName, file.Name);
                file.CopyTo(temppath, false);
            }

            // If copying subdirectories, copy them and their contents to new location.
            if (copySubDirs)
            {
                foreach (DirectoryInfo subdir in dirs)
                {
                    string temppath = Path.Combine(destDirName, subdir.Name);
                    DirectoryCopy(subdir.FullName, temppath, copySubDirs);
                }
            }
        }

আপনি অনুলিপি করতে চান তাহলে বিষয়বস্তু এর উৎস ফোল্ডার এবং সাবফোল্ডার যাও recursively আপনি কেবল এর মতো এটিকে ব্যবহার করতে পারেন:

string source = @"J:\source\";
string dest= @"J:\destination\";
DirectoryCopy(source, dest);

তবে আপনি যদি সোর্স ডিরেক্টরিটিকে নিজের করে অনুলিপি করতে চান (অনুরূপ সোর্স ফোল্ডারে আপনি ঠিক ক্লিক করেছেন এবং অনুলিপিটি ক্লিক করেছেন তারপরে আপনার গন্তব্য ফোল্ডারে আপনি পেস্ট ক্লিক করেছেন) আপনার এই জাতীয় ব্যবহার করা উচিত:

 string source = @"J:\source\";
 string dest= @"J:\destination\";
 DirectoryCopy(source, Path.Combine(dest, new DirectoryInfo(source).Name));

ইতিমধ্যে নীচে কিছু উত্তর পোস্ট করা হয়েছে: stackoverflow.com/a/45199038/1951524
মার্টিন স্নাইডার

ধন্যবাদ @ এমএ-ম্যাডিন, তবে এটি কি সোর্স ফোল্ডারটি অনুলিপি করে? বা শুধু বিষয়বস্তু?
আরশ.জান্দি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.