2010-02-11 2 views
4

C#에는 복사 된 항목의 새 이름을 생성하는 함수가 있습니까?
예를 들어, "Folder"라는 문자열이 있다면 "Copy   of   Folder ..."라는 문자열을 생성하는 함수가 필요합니다. "Copy   of   Folder"함수가 "   폴더의   복사   (1) "등등 ....복사 된 파일의 파일 이름을 생성하는 기능이 있습니까?

당신은이 같은 루프를 쓸 수
+1

당신이 정말로 하시겠습니까? "폴더의 복사 (1)"또는 "복사 (2) 폴더의"를 방법 Windows는 그것을합니까? –

답변

6

:

string baseName = @"C:\Parent\Copy of Folder", actualName = baseName; 
int index = 0; 

while(File.Exists(actualName) || Directory.Exists(actualName)) 
    actualName = baseName + " (" + (++index) + ")"; 

귀하의 사용 사례에 따라, 당신은 아마에 넣고해야 static 유틸리티 메소드.

4

@SLaks에는 기본 알고리즘이 있지만 경쟁 조건을 명심해야합니다. 파일은 File.Exists 확인과 파일 작성 사이의 시간에 다른 스레드 또는 프로세스에 의해 작성 될 수 있습니다. 여기 SLak의 알고리즘을 기반으로하는 솔루션의 개요는 다음과 같습니다

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; 
    } 
    } 
} 

파일을 열 수 없습니다 경우 다른 프로세스로 인해 예기치 않은 문제 파일이나 생성하거나 때문이다. 예기치 않은 문제가 발생한 경우 예외를 다시 throw하십시오 (예기치 않은 예외를 삼가 지 마십시오).

"new FileStream"연산이 루프 조건으로 예외를 throw하는지 여부 만 사용할 수 있지만, 오류 조건. 디버거에서 "catch on throw"예외 동작을 이용하기가 더 어려워지며 계산 예외적으로 예외가 발생합니다. 나는 당신의 복사본에 사용하고자하는 것과 같은 이름을 가진 파일 시스템 상에 파일을 가지고 있다는 것이 응용 프로그램의 맥락에서 오류가 아니라고 가정하고 있습니다. 내가 틀렸다면 파일이 존재한다면 예외가된다.

0

Microsoft에서 사용하는 "Copy of"접두사가 절대로 좋아지지 않습니다. 왜냐하면 복사본이 원본 옆에 정렬되지 않기 때문입니다. Microsoft는 Windows 7에서 "Folder - Copy", "Folder - Copy (2)"등과 같은 접미사 대신 접미어를 사용하므로 나에게 동의합니다.

0

대상 파일이 이미있는 경우 기본 Windows 기능을 사용하여 자동 이름 바꾸기를 처리하십시오. 이렇게하면 Explorer에서 파일을 복사 할 때 얻을 수있는 것과 동일한 이름을 갖게됩니다. 필요한 기능은 SHFileOperation입니다.

짧은 샘플은 다음과 같이 보일 것이다 :

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, 
    } 
} 

생성 대상 파일 이름을 얻을하는 것이 가능하다 FOF_WANTMAPPINGHANDLE 플래그를 사용. 더 읽기와 더 정교한 샘플 CodeProject의에이 위대한 문서를 참조하십시오 :

C# does Shell, Part 2

관련 문제