ファイルのバックアップ
自分で使うようにファイルのバックアップをとるプログラム書いてみた。あまりテストしてないので消すかも
Imports System.IO ''' <summary> ''' ファイルを簡単にバックアップ、リストアするためのクラス ''' ファイル、ディレクトリともに利用可能 ''' ''' バックアップされたファイルは以下の形式で名前が付けられる ''' [元のファイル名と拡張子].backup[yyyyMMdd]_[HHmm]_[ID3桁] ''' 例えば「sample.txt」というファイルをバックアップした場合 ''' 「sample.txt.backup20130702_2359_001」というファイル名になる。 ''' ディレクトリの場合も同様。 ''' </summary> ''' <remarks></remarks> Public Class Backupper Sub New() End Sub Private ReadOnly BackupFileExpression As String = "^.backup20[0-9]{2}[01][0-9][0-3][0-9]_[0-2][0-9][0-5][0-9]_[0-9]{3}" #Region "Public" ''' <summary> ''' 現在のディレクトリにバックアップファイルを作成 ''' </summary> ''' <param name="path"></param> ''' <returns></returns> ''' <remarks></remarks> Public Function Backup(ByVal path As String) As String If path Is Nothing Then Throw New ArgumentNullException() Return Backup(path, IO.Path.GetDirectoryName(path)) End Function ''' <summary> ''' 指定したディレクトリにバックアップファイルを作成 ''' </summary> ''' <param name="path"></param> ''' <param name="destDir"></param> ''' <returns></returns> ''' <remarks></remarks> Public Function Backup(ByVal path As String, ByVal destDir As String) As String If path Is Nothing Then Throw New ArgumentNullException("path") Dim manager As FileOrDirManager Try manager = FileOrDirManager.Create(path) Catch ex As ArgumentException Throw ex Return Nothing End Try If destDir Is Nothing OrElse Not IO.Directory.Exists(destDir) Then Throw New ArgumentNullException("destDir") End If Dim target As String = GenerateFileName(manager, path, destDir) If manager.Copy(path, target) Then Return target Else Return Nothing End If End Function ''' <summary> ''' バックアップファイルから復元 ''' </summary> ''' <param name="path"></param> ''' <remarks></remarks> Public Sub Restore(ByVal path As String) If path Is Nothing Then Throw New ArgumentNullException("path = Nothing") Dim manager As FileOrDirManager = FileOrDirManager.Create(path) Dim parentDirPath As String = IO.Path.GetDirectoryName(path) Dim nameWithoutExtension As String = IO.Path.GetFileNameWithoutExtension(path) Dim extension As String = IO.Path.GetExtension(path) If Not System.Text.RegularExpressions.Regex.IsMatch(extension, BackupFileExpression) Then MsgBox("指定されたパスはバックアップファイルではありません。") Return End If Dim targetPath As String = IO.Path.Combine(parentDirPath, nameWithoutExtension) '出力したい場所に既存のファイルがあるか If manager.IsExist(targetPath) Then '有るならそのファイルをバックアップファイルにする Dim backupFile As String = GenerateFileName(manager, targetPath, IO.Path.GetDirectoryName(targetPath)) If String.IsNullOrEmpty(backupFile) Then Throw New InvalidOperationException manager.Move(targetPath, backupFile) MsgBox("ディレクトリ '" & targetPath & "'は既に存在するため、バックアップファイル '" & backupFile & "'として移動しました") End If manager.Copy(path, targetPath) End Sub #End Region #Region "Private" ''' <summary> ''' ファイル名を決定 ''' </summary> ''' <param name="manager"></param> ''' <param name="path"></param> ''' <returns></returns> ''' <remarks></remarks> Private Function GenerateFileName(ByVal manager As FileOrDirManager, ByVal path As String, ByVal destDir As String) As String '純粋なファイ名を取得 例「c:\temp\sample.txt」なら「sample.txt」 Dim fileName = IO.Path.GetFileName(path) Dim resultPath As String Dim id As Integer = 0 Do id += 1 resultPath = IO.Path.Combine(destDir, GenerateNextFileName(fileName, id)) Loop While manager.IsExist(resultPath) Return resultPath End Function ''' <summary> ''' fileNameを元に次のファイル名を生成 ''' </summary> ''' <param name="fileName">純粋なファイ名 例「c:\temp\sample.txt」なら「sample.txt」</param> ''' <param name="id">ファイル名につける通し番号</param> ''' <returns></returns> ''' <remarks></remarks> Private Function GenerateNextFileName(ByVal fileName As String, ByVal id As Integer) As String Dim nameWithoutExtension As String = IO.Path.GetFileNameWithoutExtension(fileName) Dim extension As String = IO.Path.GetExtension(fileName) Dim prefix As String If System.Text.RegularExpressions.Regex.IsMatch(fileName, BackupFileExpression) Then 'バックアップファイルが存在するとき prefix = nameWithoutExtension Else prefix = fileName End If Return prefix & ".backup" & DateTime.Now.ToString("yyyyMMdd_HHmm_") & id.ToString("D3") End Function #End Region End Class
もう一個クラス必要
''' <summary> ''' ファイルとディレクトリを同様に扱うためのクラス ''' </summary> ''' <remarks></remarks> Public MustInherit Class FileOrDirManager #Region "コンストラクタ" Private Sub New() End Sub #End Region #Region "共有メソッド" Public Shared Function Create(ByVal path As String) As FileOrDirManager If IO.File.Exists(path) Then Return New FileManager() ElseIf IO.Directory.Exists(path) Then Return New DirManager() Else Throw New ArgumentException("指定されたパスが見つかりません。path =" & path) Return Nothing End If End Function #End Region #Region "抽象メソッド" Public MustOverride Function CreateInfo(ByVal path As String) As IO.FileSystemInfo Public MustOverride Function IsExist(ByVal path As String) As Boolean Public MustOverride Function Copy(ByVal source As String, ByVal target As String) As Boolean Public MustOverride Function Move(ByVal source As String, ByVal target As String) As Boolean #End Region #Region "インナークラス" Private Class FileManager Inherits FileOrDirManager Public Overrides Function CreateInfo(ByVal path As String) As System.IO.FileSystemInfo Return New IO.FileInfo(path) End Function Public Overrides Function IsExist(ByVal path As String) As Boolean Return IO.File.Exists(path) End Function Public Overrides Function Copy(ByVal source As String, ByVal target As String) As Boolean My.Computer.FileSystem.CopyFile(source, target) Return True End Function Public Overrides Function Move(ByVal source As String, ByVal target As String) As Boolean IO.File.Move(source, target) Return True End Function End Class Private Class DirManager Inherits FileOrDirManager Public Overrides Function CreateInfo(ByVal path As String) As System.IO.FileSystemInfo Return New IO.DirectoryInfo(path) End Function Public Overrides Function IsExist(ByVal path As String) As Boolean Return IO.Directory.Exists(path) End Function Public Overrides Function Copy(ByVal source As String, ByVal target As String) As Boolean My.Computer.FileSystem.CopyDirectory(source, target) Return True End Function Public Overrides Function Move(ByVal source As String, ByVal target As String) As Boolean IO.Directory.Move(source, target) Return True End Function End Class #End Region End Class
日記にコード貼り付けたら、なんか見辛いね!
というわけで久しぶりの日記でした。