-1

I want to create a data file, but before writing to the final file I want to drop it in a temporary location to avoid user confussion. As an example, I could begin with test.txt and want to have test.txt.tmp. The names could include a path, but the files may not necesarily exist (so this question is purely about string manipulation).

The closest I have been is to use Path.ChangeExtension:

string original = "test.txt";
string temp = Path.ChangeExtension(original, "tmp");

But that returns test.tmp instead. So my question is if there is a built-in method to achieve that "dual-extension" file name? I could always use brain-dead string concatenation, but I'm looking for a more safe and tested method.

Alejandro
  • 7,290
  • 4
  • 34
  • 59
  • @mjwills I want to avoid any unwanted pitfalls by using a built-in method whenever possible. Pretty much the same reason as to [why we use `Path.Combine` instead of simple concatenation](https://stackoverflow.com/q/32070934/2557263). – Alejandro Aug 23 '18 at 13:59
  • 3
    Why not you just uses `Path.ChangeExtension(original, Path.GetExtension(original) + ".tmp");`?. – Alessandro D'Andria Aug 23 '18 at 14:01
  • 1
    @Alejandro: Avoiding pitfalls is a great idea for things like `Path.Combine`. But there are no pitfalls (such as the unknown existend of a `\`) here. If your original file name is not as you expect it to be, then you'll be encountering issue well before this minor piece of logic. String concatenation is perfectly acceptable here. – Flater Aug 23 '18 at 14:06
  • @AlessandroD'Andria: While I appreciate your suggestion technically complying with the usage of `Path` logic, the inherent definition of an **extension** implies that it's the end bit of the filename. Your suggestion will always be equivalent to doing a simple concatenation, but there is a performance difference because you're taking more steps to get the same result. – Flater Aug 23 '18 at 14:07
  • @Flater Maybe "string concatenation is the best method" is a perfectly acceptable answer to me if there isn't anything else. My question is more about seeking something built-in, but the answer could be "there is no such thing". Could you post that reasoning as a full answer? – Alejandro Aug 23 '18 at 14:11
  • @Flatter personally i will go for a straight `string` concatenation, but usage of `Path.GetExtension` and `Path.ChangeExtension` make some extra work, like validating path. – Alessandro D'Andria Aug 23 '18 at 14:15

4 Answers4

4

Avoiding pitfalls is a great idea for things like Path.Combine, e.g. because you don't want to be bothered checking if there is no missing \ character.

But there are no pitfalls here.

  • If your original filename is as you expect it to be, then string concatenation will work.
  • If your original file name is not as you expect it to be, then the issue lies with whoever supplied you a faulty filename. "Shit goes in, shit comes out" is not really something your internal logic should worry about. An algorithm can only be as correct as the information that it receives.

String concatenation is perfectly acceptable here. There is no premade method here because there is no real pitfall to simply concatenating the strings.


Special shout out to AlessandroD'Andria's suggestion:

Path.ChangeExtension(original, Path.GetExtension(original) + ".tmp");

Technically, it employs Path logic and therefore fits with your criteria. I genuinely like the cleverness of following your expectations.

However, there is simply no merit to doing so. By its very nature an extension is defined as being "the last part of the filename".

Whether you do a direct string concatenation, or instead do this:

  • chop the string into two pieces (filename, extension)
  • append something to the last piece (extension + temp extension)
  • paste everything together again

The end result will always be the same. The chopping of the string is unnecessary work.

Flater
  • 12,908
  • 4
  • 39
  • 62
1

Why can't you append that string just like

if(!string.IsNullOrEmpty(Path.GetExtension(original)){
  original+= ".tmp";
}
Rahul
  • 76,197
  • 13
  • 71
  • 125
0

If you would use temp file, you can use Path.GetTempFileName();

string tempFileName = Path.GetTempFileName();

Or in your case:

 string original = "test.txt";
 string temp = "test.txt" + ".tmp";
PWND
  • 409
  • 3
  • 11
0

You should use temp file and rename the extension.

string path = Path.GetTempFileName();
// some logic on the file then rename the file and move it when you need it

string fileName = Path.GetFileName(path);
File.Move(path, path.Replace(fileName, "test.txt"));
Zysce
  • 1,200
  • 1
  • 10
  • 35
  • But that for one creates a file in the system temp folder and don't achieve my double extension requirement. – Alejandro Aug 23 '18 at 14:01
  • Why do you need a double extension ? If you use a temp file before writing the final file, it won't be accessible to user (if you use for a desktop app). – Zysce Aug 23 '18 at 14:12
  • I want it to be writen to the final destination folder. Saving to temp, then moving could be faced with permissions and disk space issues, while the same folder those would be detected at the earliest possible time. Therefore the solution I've opted for was to name it as `test.txt.tmp` while writing it, then rename to `test.txt` when finished. The user won't be able to use the file in the meanwhile (at least, not with a simple double click). Strictly speaking, any other naming would have done, but since it's a user-choosen location I want to make it as clear as possible. – Alejandro Aug 23 '18 at 14:55