FileInfoクラスを拡張してWindowsの名前重複コピー時の挙動を移植する
Windows10で同じフォルダにファイルをコピーすると「 - コピー」という接尾語が付きますよね。 移動の場合だと、「(1)」、「(2)」のような番号が付きます。 これをVBで再現しようというもの。
ええ、大したネタではありません。 時間さえあれば誰でも書けるコードです。
ついでに、FileInfoクラスはパス操作に関するメソッドが少ないので拡張メソッド追加しました。 また、VB14の新機能「String interpolation」も使ってみました。
ソースコード
Imports System.IO Imports System.Runtime.CompilerServices Module Module1 Sub Main() Dim f1 As New FileInfo("from.txt") Using f1.Create() End Using f1.Refresh() f1.MoveToOrSuffix("to.txt") Console.WriteLine(f1.Name) Dim f2 As New FileInfo("from.txt") Using f2.Create() End Using f2.Refresh() Dim f3 = f2.CopyToOrSuffix("from.txt") Console.WriteLine(f3.Name) Console.WriteLine("何かキーを押すと終了します。") Console.ReadKey() End Sub End Module ''' <summary> ''' FileInfo クラス拡張メソッド ''' </summary> Friend Module FileInfoExtension ''' <summary> ''' ディレクトリ名を取得します。 ''' </summary> ''' <param name="source"></param> ''' <returns></returns> <Extension> Function GetDirectoryName(source As FileInfo) As String Return IO.Path.GetDirectoryName(source.FullName) End Function ''' <summary> ''' ファイル名を拡張子を付けずに返します。 ''' </summary> ''' <param name="source"></param> ''' <returns></returns> <Extension> Function GetNameWithoutExtension(source As FileInfo) As String Return IO.Path.GetFileNameWithoutExtension(source.FullName) End Function ''' <summary> ''' ファイル名を拡張子を返します。 ''' </summary> ''' <param name="source"></param> ''' <returns></returns> <Extension> Function GetExtension(source As FileInfo) As String Return IO.Path.GetExtension(source.FullName) End Function ''' <summary> ''' ファイル名に接尾語を追加します。 ''' </summary> ''' <param name="source"></param> ''' <param name="suffix"></param> ''' <returns></returns> <Extension> Function AddSuffix(source As FileInfo, suffix As String) As FileInfo Dim name As String = $"{source.GetNameWithoutExtension}{suffix}{source.GetExtension}" Dim f As New FileInfo(IO.Path.Combine(source.GetDirectoryName, name)) Return f End Function ''' <summary> ''' 新しい場所に移動します。 ''' 同名のファイルが既に存在する場合は接尾語(番号)を付与します。 ''' </summary> ''' <param name="source"></param> ''' <param name="destFileName"></param> ''' <returns></returns> <Extension> Function MoveToOrSuffix(source As FileInfo, destFileName As String) As FileInfo Dim f As New FileInfo(destFileName) If f.Exists = False Then source.MoveTo(f.FullName) f.Refresh() Return f End If For i As Integer = 1 To 99 Dim dest = f.AddSuffix($"({i})") If dest.Exists = False Then source.MoveTo(dest.FullName) dest.Refresh() Return dest End If Next Throw New Exception("移動失敗") End Function ''' <summary> ''' 既存のファイルを上書きできないようにして、既存のファイルを新しいファイルにコピーします。 ''' 同名のファイルが既に存在する場合は接尾語( - コピー)を付与します。 ''' </summary> ''' <param name="source"></param> ''' <param name="destFileName"></param> ''' <returns></returns> <Extension> Function CopyToOrSuffix(source As FileInfo, destFileName As String) As FileInfo Dim suffix As String = " - コピー" Dim dest As New FileInfo(destFileName) For i As Integer = 1 To 99 If dest.Exists = False Then source.CopyTo(dest.FullName) dest.Refresh() Return dest End If dest = dest.AddSuffix(suffix) Next Throw New Exception("コピー失敗") End Function End Module
実行結果
to(5).txt from - コピー - コピー - コピー - コピー - コピー - コピー.txt 何かキーを押すと終了します。