Create unique files in another directory

I am currently grabbing multiple .txt files from the directory I specified (sourceDirectory). I am generating new .csv files with the same name as the .txt files - one CSV file for each .txt file.

However, I want to generate these new files in a different directory I specified (directoryPath). If I run my program after creating these files in the source directory, however, if I run my program again, it will now generate files in the target directory.

Below is my code where I complete the above:

static void Main(string[] args)
    {
        string sourceDirectory = @"C:directoryWhereTXTFilesAre";

        var txtFiles = Directory.EnumerateFiles(sourceDirectory, "*.txt", SearchOption.AllDirectories);

        foreach (string currentFile in txtFiles)
        {
            readFile(currentFile);
        }

        string directoryPath = @"C:\destinationForCSVFiles"; 
    }

      

Then I create new .csv files based on the original .txt file like this:

static FileStream CreateFileWithUniqueName(string folder, string fileName, int maxAttempts = 1024)
        {
            var fileBase = Path.GetFileNameWithoutExtension(fileName);
            var ext = Path.GetExtension(fileName);

            // build hash set of filenames for performance
            var files = new HashSet<string> (Directory.GetFiles(folder));

            for (var index = 0; index < maxAttempts; index++)
            {
                // first try with the original filename, else try incrementally adding an index
                var name = (index == 0)
                    ? fileName
                    : String.Format("{0} ({1}){2}", fileBase, index, ext);

                // check if exists
                var fullPath = Path.Combine(folder, name);
                string CSVfileName = Path.ChangeExtension(fullPath, ".csv");
                if (files.Contains(CSVfileName))
                    continue;

                // try to create the file
                try
                {
                    return new FileStream(CSVfileName, FileMode.CreateNew, FileAccess.Write);
                }
                catch (DirectoryNotFoundException) { throw; }
                catch (DriveNotFoundException) { throw; }
                catch (IOException)
                {

                }
           }      

      

I don't understand why it creates the .csv files initially in the same directory as the .txt files, and then the second time I run my code it creates in the Path directory.

Output required: sourceDirectory is left as is with only .txt and directoryPath files to store .csv files.

The only other place I call CreateFileWithUniqueName is in my readFile method, the code is below:

     using (var stream = CreateFileWithUniqueName(@"C:destinationFilePath", currentFile))
                    {
                        Console.WriteLine("Created \"" + stream.Name + "\"");
                newFileName = stream.Name;
                Globals.CleanedFileName = newFileName;
    }

      

+3


source to share


1 answer


It seems that you are passing in the full filename of the original file. This confuses Path.Combine inside CreateFileWithUniqueFilename because you are falling into this subtle remark found in Path.Combine documentation

paths must be an array of path parts to combine. If one of the subsequent paths is an absolute path, then the combine operation is dropped from that absolute path, discarding all previous combined paths.

You can fix it easily with

 using (var stream = CreateFileWithUniqueName(@"C:\destinationFilePath",  
                                        Path.GetFileName(currentFile)))
 {
      Console.WriteLine("Created \"" + stream.Name + "\"");
      newFileName = stream.Name;
      Globals.CleanedFileName = newFileName;
}

      



Or is it better to extract the filename without path inside CreateFileWithUniqueName

static FileStream CreateFileWithUniqueName(string folder, string fileName, int maxAttempts = 1024)
{
    var fileBase = Path.GetFileName(fileName);
    fileBase = Path.GetFileNameWithoutExtension(fileBase);
    var ext = Path.GetExtension(fileBase);

      

also you have to create your CSV file name using the stripped file name

    var name = (index == 0)
        ? String.Format("{0}{1}", fileBase, ext);
        : String.Format("{0} ({1}){2}", fileBase, index, ext);
    var fullPath = Path.Combine(folder, name);
    string CSVfileName = Path.ChangeExtension(fullPath, ".csv");
    if (files.Contains(CSVfileName))
        continue;

      

+1


source







All Articles