Nice programing

파일이 이미 Windows 방식으로 존재하는 경우 자동으로 이름 바꾸기

nicepro 2021. 1. 9. 11:36
반응형

파일이 이미 Windows 방식으로 존재하는 경우 자동으로 이름 바꾸기


내 C # 코드는 입력을 기반으로 여러 텍스트 파일을 생성하고 폴더에 저장합니다. 또한 텍스트 파일의 이름이 입력과 동일하다고 가정합니다. (입력에는 문자 만 포함되어 있음) 두 파일의 이름이 같으면 이전 파일을 덮어 쓰는 것입니다. 하지만 두 파일을 모두 유지하고 싶습니다.

두 번째 파일 이름에 현재 날짜 시간이나 임의의 숫자를 추가하고 싶지 않습니다. 대신 Windows와 같은 방식으로 수행하고 싶습니다. fisrt 파일 이름이 AAA.txt이면 두 번째 파일 이름은 AAA (2) .txt, 세 번째 파일 이름은 AAA (3) .txt ..... N 번째 파일 이름은 AAA (N) .txt가됩니다. .

string[] allFiles = Directory.GetFiles(folderPath).Select(filename => Path.GetFileNameWithoutExtension(filename)).ToArray();
        foreach (var item in allFiles)
        {
            //newFileName is the txt file which is going to be saved in the provided folder
            if (newFileName.Equals(item, StringComparison.InvariantCultureIgnoreCase))
            {
                // What to do here ?                
            }
        }

그러면 tempFileName이있는 파일의 존재를 확인하고 디렉터리에없는 이름을 찾을 때까지 번호를 1 씩 증가시킵니다.

int count = 1;

string fileNameOnly = Path.GetFileNameWithoutExtension(fullPath);
string extension = Path.GetExtension(fullPath);
string path = Path.GetDirectoryName(fullPath);
string newFullPath = fullPath;

while(File.Exists(newFullPath)) 
{
    string tempFileName = string.Format("{0}({1})", fileNameOnly, count++);
    newFullPath = Path.Combine(path, tempFileName + extension);
}

이 코드를 사용하여 파일 이름이 "Test (3) .txt"이면 "Test (4) .txt"가됩니다.

public static string GetUniqueFilePath(string filepath)
{
    if (File.Exists(filepath))
    {
        string folder = Path.GetDirectoryName(filepath);
        string filename = Path.GetFileNameWithoutExtension(filepath);
        string extension = Path.GetExtension(filepath);
        int number = 1;

        Match regex = Regex.Match(filepath, @"(.+) \((\d+)\)\.\w+");

        if (regex.Success)
        {
            filename = regex.Groups[1].Value;
            number = int.Parse(regex.Groups[2].Value);
        }

        do
        {
            number++;
            filepath = Path.Combine(folder, string.Format("{0} ({1}){2}", filename, number, extension));
        }
        while (File.Exists(filepath));
    }

    return filepath;
}

다른 예는 파일 이름 / 확장자를 고려하지 않습니다.

여기 있습니다 :

    public static string GetUniqueFilename(string fullPath)
    {
        if (!Path.IsPathRooted(fullPath))
            fullPath = Path.GetFullPath(fullPath);
        if (File.Exists(fullPath))
        {
            String filename = Path.GetFileName(fullPath);
            String path = fullPath.Substring(0, fullPath.Length - filename.Length);
            String filenameWOExt = Path.GetFileNameWithoutExtension(fullPath);
            String ext = Path.GetExtension(fullPath);
            int n = 1;
            do
            {
                fullPath = Path.Combine(path, String.Format("{0} ({1}){2}", filenameWOExt, (n++), ext));
            }
            while (File.Exists(fullPath));
        }
        return fullPath;
    }

그냥 어때 :

int count = 1;
String tempFileName = newFileName;

foreach (var item in allFiles)
{
  if (tempFileName.Equals(item, StringComparison.InvariantCultureIgnoreCase))
  {
    tempFileName = String.Format("{0}({1})", newFileName, count++);
  }
}

원래 파일 이름이 없으면 원래 파일 이름을 사용하고, 그렇지 않으면 괄호 안에 색인이있는 새 파일 이름을 사용합니다 (이 코드는 확장자를 고려하지 않음). 새로 생성 된 이름 "text (001)"이 사용되면 유효한 사용되지 않은 파일 이름을 찾을 때까지 증가합니다.


public static string AutoRenameFilename(FileInfo file)
    {
        var filename = file.Name.Replace(file.Extension, string.Empty);
        var dir = file.Directory.FullName;
        var ext = file.Extension;

        if (file.Exists)
        {
            int count = 0;
            string added;

            do
            {
                count++;
                added = "(" + count + ")";
            } while (File.Exists(dir + "\\" + filename + " " + added + ext));

            filename += " " + added;
        }

        return (dir + filename + ext);
    }

int count= 0;

file은 파일의 이름입니다.

while (File.Exists(fullpathwithfilename))  //this will check for existence of file
{ 
// below line names new file from file.xls to file1.xls   
fullpathwithfilename= fullpathwithfilename.Replace("file.xls", "file"+count+".xls"); 

count++;
}

파일을 이동하는 솔루션을 찾고 있었고 대상 파일 이름이 아직 사용되지 않았는지 확인했습니다. Windows와 동일한 논리를 따르고 중복 파일 뒤에 대괄호와 함께 숫자를 추가합니다.

@ cadrell0 덕분에 최고의 답변은 다음 솔루션에 도달하는 데 도움이되었습니다.

    /// <summary>
    /// Generates full file path for a file that is to be moved to a destinationFolderDir. 
    /// 
    /// This method takes into account the possiblity of the file already existing, 
    /// and will append number surrounded with brackets to the file name.
    /// 
    /// E.g. if D:\DestinationDir contains file name file.txt,
    /// and your fileToMoveFullPath is D:\Source\file.txt, the generated path will be D:\DestinationDir\file(1).txt
    /// 
    /// </summary>
    /// <param name="destinationFolderDir">E.g. D:\DestinationDir </param>
    /// <param name="fileToMoveFullPath">D:\Source\file.txt</param>
    /// <returns></returns>
    public string GetFullFilePathWithDuplicatesTakenInMind(string destinationFolderDir, string fileToMoveFullPath)
    {
        string destinationPathWithDuplicatesTakenInMind;

        string fileNameWithExtension = Path.GetFileName(fileToMoveFullPath);
        string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(fileToMoveFullPath);
        string fileNameExtension = Path.GetExtension(fileToMoveFullPath);

        destinationPathWithDuplicatesTakenInMind = Path.Combine(destinationFolderDir, fileNameWithExtension);

        int count = 0;
        while (File.Exists(destinationPathWithDuplicatesTakenInMind))
        {
            destinationPathWithDuplicatesTakenInMind = Path.Combine(destinationFolderDir, $"{fileNameWithoutExtension}({count}){fileNameExtension}");
            count = count + 1; // sorry, not a fan of the ++ operator.
        }

        return destinationPathWithDuplicatesTakenInMind;
    }

You can declare a Dictionary<string,int> to keep the number of times each root file name was saved. After that, on your Save method, just increase the counter and append it to the base file name:

var key = fileName.ToLower();
string newFileName;
if(!_dictionary.ContainsKey(key))
{
    newFileName = fileName;
    _dictionary.Add(key,0);
}
else
{
    _dictionary[key]++;
   newFileName = String.Format("{0}({1})", fileName, _dictionary[key])
}

This way, you'll have a counter for each distinct file name: AAA(1), AAA(2); BBB(1)...


It's working fine now. thanks guys for the answers..

string[] allFiles = Directory.GetFiles(folderPath).Select(filename => Path.GetFileNameWithoutExtension(filename)).ToArray();
        string tempFileName = fileName;
        int count = 1;
        while (allFiles.Contains(tempFileName ))
        {
            tempFileName = String.Format("{0} ({1})", fileName, count++); 
        }

        output = Path.Combine(folderPath, tempFileName );
        string fullPath=output + ".xml";

With regard to Giuseppe's comment on the way windows renames files I worked on a version that finds any existing index i.e. (2) in the file name and renames the file as per windows accordingly. The sourceFileName is assumed to be valid and the user is assumed to have write permission on the destination folder by this point:

using System.IO;
using System.Text.RegularExpressions;

    private void RenameDiskFileToMSUnique(string sourceFileName)
    {
        string destFileName = "";
        long n = 1;
        // ensure the full path is qualified
        if (!Path.IsPathRooted(sourceFileName)) { sourceFileName = Path.GetFullPath(sourceFileName); }

        string filepath = Path.GetDirectoryName(sourceFileName);
        string fileNameWOExt = Path.GetFileNameWithoutExtension(sourceFileName);
        string fileNameSuffix = "";
        string fileNameExt = Path.GetExtension(sourceFileName);
        // if the name includes the text "(0-9)" then we have a filename, instance number and suffix  
        Regex r = new Regex(@"\(\d+\)");
        Match match = r.Match(fileNameWOExt);
        if (match.Success) // the pattern (0-9) was found
        {
            // text after the match
            if (fileNameWOExt.Length > match.Index + match.Length) // remove the format and create the suffix
            {
                fileNameSuffix = fileNameWOExt.Substring(match.Index + match.Length, fileNameWOExt.Length - (match.Index + match.Length));
                fileNameWOExt = fileNameWOExt.Substring(0, match.Index);
            }
            else // remove the format at the end
            {
                fileNameWOExt = fileNameWOExt.Substring(0, fileNameWOExt.Length - match.Length);
            }
            // increment the numeric in the name
            n = Convert.ToInt64(match.Value.Substring(1, match.Length - 2)) + 1;
        }
        // format variation: indexed text retains the original layout, new suffixed text inserts a space!
        do
        {
            if (match.Success) // the text was already indexed
            {
                if (fileNameSuffix.Length > 0)
                {
                    destFileName = Path.Combine(filepath, String.Format("{0}({1}){2}{3}", fileNameWOExt, (n++), fileNameSuffix, fileNameExt));
                }
                else
                {
                    destFileName = Path.Combine(filepath, String.Format("{0}({1}){2}", fileNameWOExt, (n++), fileNameExt));
                }
            }
            else // we are adding a new index
            {
                destFileName = Path.Combine(filepath, String.Format("{0} ({1}){2}", fileNameWOExt, (n++), fileNameExt));
            }
        }
        while (File.Exists(destFileName));

        File.Copy(sourceFileName, destFileName);
    }

ReferenceURL : https://stackoverflow.com/questions/13049732/automatically-rename-a-file-if-it-already-exists-in-windows-way

반응형