kenju's blog

About Programming, Mathematics, Security and Blockchain

FileSystemの互換性を保つファイル名のエスケープ

先日の仕事で、maxOS, Windows, Linuxで基本的に互換性のあるファイル・ディレクトリ名を出力する必要にでくわしました。

Windowsにおける禁止単語

Naming Files, Paths, and Namespaces (Windows)

Windowsをあまり使わなかったのですが、Windowsでは↓の文字が使えないとのこと。

CON, PRN, AUX, NUL, COM1, COM2, COM3, COM4, COM5, COM6, COM7, COM8, COM9, LPT1, LPT2, LPT3, LPT4, LPT5, LPT6, LPT7, LPT8, and LPT9. Also avoid these names followed immediately by an extension; for example, NUL.txt is not recommended.

各OSのFileSystem上で使えない禁止文字

Filename - Wikipedia

/はUnix系では使えません。Windowsの場合、?%なども使えません。

コード例

“Windowsにおける禁止単語"の場合、_を接頭辞に付与していvalidなファイル名に変換しています。 ファイル名に禁止文字が含まれる場合、_にエスケープしています。

以下はRubyでのコード例です:

def self.escape(path, escape_char = '_')
    reserved_words_windows = Set.new([
        "CON", "PRN", "AUX", "NUL",
        "COM1", "COM2", "COM3", "COM4", "COM5", "COM6", "COM7", "COM8", "COM9",
        "LPT1", "LPT2", "LPT3", "LPT4", "LPT5", "LPT6", "LPT7", "LPT8", "LPT9"
    ])
    return "#{escape_char}#{path}" if reserved_words.include?(File.basename(path, ".*").upcase)
    path.gsub(%r{[/\\?%*:|"<>. ]}, escape_char)
end