【问题标题】:How to make file names sequentially infinite when creating additional files in the Windows form of C#?以 C# 的 Windows 形式创建附加文件时,如何使文件名顺序无限?
【发布时间】:2017-12-21 02:25:15
【问题描述】:

每次我单击 Windows 窗体上的按钮时, 我想创建一个无限顺序地创建文件的程序。

例如, 这是一个 a.txt 文件。 当我以 c# 的 windows 形式将其创建为具有新名称的文件时 我想创建 a-2.txt。 如果我继续添加更多文件,我想无限地依次制作 a-3.txt、a-4.txt、a-5.txt ....。

例如这里是那些文件。 a-2.txt、a-3.txt、a-4.txt、a-5.txt 如果我随机删除a-3.txt,a-4.txt,不知怎么弄a-3.txt,a-4.txt,a-6.txt,a-7.txt....每次我单击 Windows 窗体上的按钮。 原因是a-2.txt、a-5.txt还残留。

【问题讨论】:

  • 所以你想“创建一个程序”?是什么阻止你这样做?你没有编译器?你对编程一无所知?你试过写东西吗?愿意展示给我们看吗?
  • 不可能。一个文件夹中的文件不能超过 4,294,967,295 个。
  • 如果您甚至接近 4,294,967,295,您将需要一个如何不编写软件的奖励。
  • 非常感谢您关注我的问题。很抱歉打扰你。我只是想知道如何制作代码或程序。我想知道。请帮帮我。
  • 非常感谢您关注我的问题。很抱歉打扰你。我只是想知道如何制作代码或程序。我想知道。换句话说,我有一个问题。这就是你如何通过添加一个数字来创建一个唯一的文件名,然后在我删除一些文件之后以及如何创建一个删除的文件。

标签: c# winforms filenames


【解决方案1】:

因为你没有包含任何代码,我会给你一个没有代码的答案,为你指明正确的方向

创建文件时,您需要列出目录中的所有文件,将数字分开,然后对它们进行排序以获得下一个可用的数字,以了解要创建的文件名。

您可以通过枚举目录中的文件来获取列表来做到这一点

var fileList = Directory.EnumerateDirectories(dirPath);

然后你会遇到一些简单的问题:拆分这些文件路径以获取名称,然后拆分名称以生成数字列表,然后找到下一个应该创建的数字

要从您可以使用的路径中获取文件名,Path.GetFileNameWithoutExtension

要从文件名中获取数字,您可以使用RegEx

要将列表转换为int 的列表,您可以使用Linq

【讨论】:

  • 很抱歉打扰您。
  • 它实际上在一个工作示例中解决了所有技术问题。
【解决方案2】:

你应该使用类似的东西,但是添加你的本地路径,正如萨鲁曼所说,修剪返回的路径。

下面的代码应该检查 a.txt 并调用另一个函数来创建它,如果它不存在。如果 a.txt 确实存在,它会查找所有具有适当名称的文件,并将它们拆分为“-”和“.”。仅提取数字,将数字转换为列表并对其进行排序。

计数器查找列表中的第一个间隙,如果找到则使用它,否则选择适当的 1 更高的数字。这只是草草写下,没有经过测试(VS 目前不想工作),所以你可能需要调试。

        if (System.IO.File.Exists("a.txt"))
        {
            System.Text.RegularExpressions.Regex regex = new System.Text.RegularExpressions.Regex("^a-\\d+\\.txt$");
            int[] numbers = System.IO.Directory.GetFiles("path", "a-*.txt").Where(x => regex.IsMatch(x)).Select(x => int.Parse(x.Split('-', '.')[1])).OrderBy(x => x).ToArray();
            for (int c = 0; c < numbers.Length; c++)
                if (numbers[c] != c + 2)
                {
                    CreateFile(string.Concat("a-", (c + 2).ToString(), ".txt"));
                    break;
                }
            CreateFile(string.Concat("a-", (numbers.Length + 2).ToString(), ".txt"));
        }
        else
        {
            CreateFile("a.txt");
        }

【讨论】:

  • 非常感谢您的建议。我一定会调试你的代码。再次感谢您。
  • 你能告诉我“^a-\\d+\\.txt$”是什么吗?
  • 该字符串称为正则表达式。正则表达式是一个对象,它描述了字符串的格式,并允许您执行诸如“传入的字符串是否具有某种格式”或“返回字符串的这一部分”之类的操作。 Caret 匹配字符串的开头,a 和破折号分别查找 a 和破折号。反斜杠 d 查找数字。加号使得它不是寻找一个数字,而是寻找一个或多个数字。反斜杠点查找一个点。 txt 查找 txt,$ 查找字符串的结尾。
  • 最终结果是我们寻找一个以“a-”开头的开头,后跟1个或多个数字,然后是“.txt”,然后字符串结束。 aa-2.txt 将不匹配。 a-2.txt 会匹配。 a-25.txt 会匹配。 a-25.txte 不匹配。如果 a-1.txt 存在,这将出现错误,因为在 a-1 上的循环不存在,但将 .Where(x => regex.IsMatch(x)) 更改为 .Where(x => regex.IsMatch (x) && x != "a-1.txt") 将消除该潜在错误。
  • 很抱歉回答晚了。我知道了。 ^^ 非常感谢。
【解决方案3】:

您可以使用 Windows API GetTempFileName 指定:

  • 您想要文件的位置
  • 前缀字符串
  • 是否应该是唯一的

规格:

UINT WINAPI GetTempFileName(
  _In_  LPCTSTR lpPathName,
  _In_  LPCTSTR lpPrefixString,
  _In_  UINT    uUnique,
  _Out_ LPTSTR  lpTempFileName
);

MSDN:

为临时文件创建一个名称。如果生成了唯一的文件名,则创建一个空文件并释放它的句柄;否则,只会生成一个文件名。

具体来说:

u唯一 [in] 用于创建临时文件名的无符号整数。有关详细信息,请参阅备注。

如果 uUnique 为零,该函数会尝试使用当前系统时间形成一个唯一的文件名。如果文件已经存在,则数字加一并且函数测试该文件是否已经存在。这一直持续到找到唯一的文件名;该函数使用该名称创建一个文件并关闭它。请注意,当 uUnique 非零时,该函数不会尝试验证文件名的唯一性。

为什么要使用这个?

这里的其他答案虽然很好,但涉及您获取所有预先存在的文件(其中可能有很多),然后计算文件名,然后在创建文件之前测试其唯一性,到那时,同名文件可能是由另一个进程创建。尽管GetTempFileName 有一个类似循环的唯一性,但它只需要您进行一次调用和一行代码,并且不需要文件名预取。

更多

【讨论】:

  • 非常感谢您的回答和建议。^^
【解决方案4】:

这是一个程序,用于从文件列表中获取下一个连续 id,然后使用该 id 写入一个新文件

注意:我很无聊这样做,我认为这给了你所有的 您需要进一步了解的信息

class Program
{

   private static int GetNextId(List<int> ids)
   {
      int i;
      for (i = 0; ids[i] == i; i++); // search for first missing id
      return i;
   }

   static void Main(string[] args)
   {
      var myPath = @"d:\test"; // your path

      var fileNames = Directory.EnumerateFiles(myPath) // get files in your path
         .Select(Path.GetFileNameWithoutExtension)     // get the file name from the full path
         .ToList(); // convert it to list

      var ids = fileNames.Select(fileName => 
      Convert.ToInt32(fileName.Substring(fileName.IndexOf("-") + 1))) // get the index of dash, then get the rest of the name (id)
         .ToList(); // convert it to a list of int

      ids.Sort(); // sort it to make sure its in order

      var nextFileId = GetNextId(ids); // get the consecutive id 

      // write a new file
      using (var file = File.Create(Path.Combine(myPath, $"myFile-{nextFileId}")))
      {
         // file.write(); write stuff here
      }
   }
}

【讨论】:

  • 非常感谢您的建议和回答。
猜你喜欢
  • 2011-01-24
  • 2014-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-10-20
相关资源
最近更新 更多