minato128 blog

minato128の公開メモ帳です。

WindowsOSで保存するときのファイル名のエスケープ処理

実行環境

Windows7 64bit
VS2010(.NET 2.0)

備考

  • ファイル名として不正な文字は全角変換する。
  • StrConvの全角変換は"\"が対応してないしVB関数だから、割り切って変換する文字だけDictionaryで持つことにした。
  • Dictionaryで指定した文字以外は"_"に変換。

ソース

	''' <summary>
	''' Windowsファイル名の変換用リスト
	''' </summary>
	''' <remarks></remarks>
	Private Shared ReadOnly _escapeCharList As Dictionary(Of String, String) = New Dictionary(Of String, String) From {{"\", "¥"}, {"/", "/"}, {":", ":"}, {"*", "*"}, {"?", "?"}, {"""", Chr(&H8168)}, {"<", "<"}, {">", ">"}, {"|", "|"}}
	''' <summary>
	''' Windowsファイル名として使用できない文字を変換して返します。
	''' </summary>
	''' <param name="fileName">ファイル名(ファイルパスではありません)</param>
	Public Shared Function EscapeFileName(fileName As String) As String
	    If String.IsNullOrEmpty(fileName) Then
	        Return String.Empty
	    End If

	    Dim escaped As String = fileName
	    Dim invalidFileNameChars As Char() = IO.Path.GetInvalidFileNameChars()
	    For Each invalidChar As Char In invalidFileNameChars
	        If escaped.Contains(invalidChar) Then
	            If _escapeCharList.ContainsKey(invalidChar) Then
	                escaped = escaped.Replace(invalidChar, _escapeCharList(invalidChar))
	            Else
	                escaped = escaped.Replace(invalidChar, "_")
	            End If
	        End If
	    Next

	    Return escaped
	End Function
    '''<summary>
    '''EscapeFileName のテスト
    '''</summary>
    <TestMethod()>
    Public Sub EscapeFileNameTest()
        Dim invalidFileNameChars As Char() = IO.Path.GetInvalidFileNameChars()
        Dim invalidChar As String = String.Empty
        invalidFileNameChars.ToList.ForEach(Sub(e) invalidChar += e)
        Assert.AreEqual(Chr(&H8168) & "<>|________________________________:*?¥/", StringUtil.EscapeFileName(invalidChar))

        Assert.AreEqual(String.Empty, StringUtil.EscapeFileName(Nothing))
        Assert.AreEqual(String.Empty, StringUtil.EscapeFileName(String.Empty))
        Assert.AreEqual("¥/:*?<>|", StringUtil.EscapeFileName("\/:*?<>|"))
        Assert.AreEqual("¥/:*?<>|" & Chr(&H8168), StringUtil.EscapeFileName("\/:*?<>|"""))
        Assert.AreEqual("::1", StringUtil.EscapeFileName("::1"))
    End Sub