Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When is p.stem() + p.extension() != p.filename()?

In the std::filesystem::path::extension() page on cppreference.com, it says the following:

On a non-POSIX system, it is possible that p.stem() + p.extension() != p.filename() even though generic-format versions are the same.

When could this occur?

like image 842
Arlo Taylor Avatar asked Sep 10 '25 19:09

Arlo Taylor


2 Answers

NTFS supports alternative data streams. The stream selection goes after the extension, such as file.extension:stream:$DATA. This is part of the file path (to be opened) but not stem() or extension(). It is however considered filename()

MSVC will remove these parts when returning stem or extension. Curiously, replace_extension() will remove the stream, as does replace_filename. It seems like even Microsoft only half-cares about these. Their documentation doesn't even mention it.

#include <iostream>
#include <filesystem>

int main()
{
    namespace fs = std::filesystem;
    fs::path p { "C:/foo/bar.baz:stream:$DATA"};
    std::cout << "stem\t" << p.stem() << '\n'
              << "extension\t" << p.extension() << '\n'
              << "filename\t" << p.filename() << '\n'
              << "replace_extension\t" << p.replace_extension("quz") << '\n';

}

Prints

stem              "bar"
extension         ".baz"
filename          "bar.baz:stream:$DATA"
replace_extension "C:/foo/bar.quz"

Other filesystems have similar features, most notably any of Apple's recent filesystems with their resource fork. It can be addressed as file.extension/rsrc or file.extension/..namedfork/rsrc. See for example Does APFS actually support Named Forks or just Resource Forks and Extended Attributes? I have no idea if and how the first syntax can even be recognized without accessing the filesystem.

Similarly, OpenVMS supports a file version suffix, as noted by @grawity. In its nomenclature foo.bar;1 is version ;1 of the file foo with type .bar. The specification also allows for foo.bar.1.

like image 192
Homer512 Avatar answered Sep 15 '25 12:09

Homer512


I have seen a file system where a JPG file named photo would have a filename of photo[JPG]. Ages ago. But on POSIX, if you are careless you might produce photoJPG or photo..JPG instead of photo.JPG. I'd look for a library function that is guaranteed to always return the correct result instead of relying on string concatenation.

like image 38
gnasher729 Avatar answered Sep 15 '25 13:09

gnasher729