Is there a function to create the file name of the copied file?

Does C # have any functions to create a new name for the copied item?

For example, if I have a line called "Folder", I need a function to create the line "Copy of Folder" .... and given the line "Copy of Folder" the function should create "Copy of Folder (1)" and so .d ....

+4
source share
4 answers

You can write a loop, for example:

string baseName = @"C:\Parent\Copy of Folder", actualName = baseName; int index = 0; while(File.Exists(actualName) || Directory.Exists(actualName)) actualName = baseName + " (" + (++index) + ")"; 

Depending on your use case, you should probably put it in the static utility method.

+6
source

@SLaks has a basic algorithm, but you need to keep in mind the race conditions. A file can be created by another thread or process during the time between checking File.Exists and creating the file. Here is a solution scheme based on the SLak algorithm:

 FileStream fileCopy; while(File.Exists(actualName) || Directory.Exists(acutalName)) { actualName = baseName + " (" + (++index) + ")"; try { fileCopy = new FileStream(actualName, FileMode.CreateNew); } catch (IOException) { if (!File.Exists(actualName)) { throw; } } } 

If you are unable to open the file, this happens either because some other process created the file, or because of some unexpected problem. Repeat throwing exceptions in case of unexpected problem (never swallow unexpected exceptions.)

You could simply use whether the “new FileStream” operation throws an exception as a loop condition, but I avoid throwing exceptions for error-free conditions. This makes it harder to use the “broken” behavior of exceptions in the debugger, and exceptions are expensive calculations. I assume that it is not a mistake in the context of your application to have a file in the file system with the same name that you would like to use for your copy. If I am mistaken about this, then the exception if the file exists is appropriate in my mind.

+4
source

I never liked the "Copy" prefix used by Microsoft, because copies are not sorted next to the originals. Microsoft in Windows 7 now agrees with me (which is always nice), because instead of a suffix, a suffix is ​​used, something like "Folder - Copy", "Folder - Copy (2)", etc.

0
source

You can also use the built-in Windows function to handle automatic renaming if the target file already exists. This way you get the same name that you get when copying a file in Explorer. Required SHFileOperation function.

A short sample will look like this:

 using System; using System.ComponentModel; using System.Diagnostics; using System.Runtime.InteropServices; class Program { static void Main(string[] args) { string file = @"C:\tmp\test.txt"; try { SHFILEOPSTRUCT fileOp = new SHFILEOPSTRUCT(); fileOp.wFunc = FO_Func.FO_COPY; fileOp.fFlags = (ushort)(FILEOP_FLAGS.FOF_RENAMEONCOLLISION); // file names need double-null termination fileOp.pFrom = file + '\0' + '\0'; // use the same name as target for demo purpose fileOp.pTo = file + '\0' + '\0'; int hRes = SHFileOperation(ref fileOp); if (hRes != 0) { throw new Win32Exception(hRes); } } catch (Exception ex) { Trace.WriteLine(ex); } } [DllImport("shell32.dll", CharSet = CharSet.Unicode)] static extern int SHFileOperation([In] ref SHFILEOPSTRUCT lpFileOp); [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode, Pack = 1)] struct SHFILEOPSTRUCT { public IntPtr hwnd; public FO_Func wFunc; [MarshalAs(UnmanagedType.LPWStr)] public string pFrom; [MarshalAs(UnmanagedType.LPWStr)] public string pTo; public ushort fFlags; public Int32 fAnyOperationsAborted; public IntPtr hNameMappings; [MarshalAs(UnmanagedType.LPWStr)] public string lpszProgressTitle; } public enum FO_Func : uint { FO_MOVE = 0x0001, FO_COPY = 0x0002, FO_DELETE = 0x0003, FO_RENAME = 0x0004, } [Flags] public enum FILEOP_FLAGS : ushort { FOF_MULTIDESTFILES = 0x0001, FOF_CONFIRMMOUSE = 0x0002, FOF_SILENT = 0x0004, FOF_RENAMEONCOLLISION = 0x0008, FOF_NOCONFIRMATION = 0x0010, FOF_WANTMAPPINGHANDLE = 0x0020, FOF_ALLOWUNDO = 0x0040, FOF_FILESONLY = 0x0080, FOF_SIMPLEPROGRESS = 0x0100, FOF_NOCONFIRMMKDIR = 0x0200, FOF_NOERRORUI = 0x0400, FOF_NOCOPYSECURITYATTRIBS = 0x0800, FOF_NORECURSION = 0x1000, FOF_NO_CONNECTED_ELEMENTS = 0x2000, FOF_WANTNUKEWARNING = 0x4000, FOF_NORECURSEREPARSE = 0x8000, } } 

Using the flag FOF_WANTMAPPINGHANDLE also possible to get the generated name of the target file. For further reading and more detailed examples, see this wonderful CodeProject article:

C # makes Shell part 2

0
source

Source: https://habr.com/ru/post/1301007/


All Articles