- PR -

ファイルをコピーする場合の処理

投稿者投稿内容
Morley
会議室デビュー日: 2003/02/27
投稿数: 18
投稿日時: 2006-03-10 00:15
些細なことなのですけど、
ファイルをコピーする場合、
Try-Catchで例外をキャッチする処理か、
元ファイルが存在するかチェックしてから処理するほうか、
どちらがよいでしょうか?

[例1]
Try
System.IO.File.Copy("c:\\sample.txt", "d:\\sample.txt", True)

Catch ex As Exception
MsgBox(ex.Message, MsgBoxStyle.OkOnly + MsgBoxStyle.Critical, "エラー")
End Try

[例2]
If System.IO.File.Exists("c:\\sample.txt") = False Then
MsgBox("ファイルが見つかりません", MsgBoxStyle.OkOnly + MsgBoxStyle.Critical, "エラー")
Else
System.IO.File.Copy("c:\\sample.txt", "d:\\sample.txt", True)
End If
囚人
ぬし
会議室デビュー日: 2005/08/13
投稿数: 1019
投稿日時: 2006-03-10 00:26
ファイルコピーに限らず,例外を避けられるなら避けるべきです.
という事で,当然まずチェックです.

より良いのはこれかと.
[例3]
コード:
Try 
	If System.IO.File.Exists("c:\\\\sample.txt") = False Then 
		MsgBox("ファイルが見つかりません", MsgBoxStyle.OkOnly + MsgBoxStyle.Critical, "エラー") 
	Else 
		System.IO.File.Copy("c:\\\\sample.txt", "d:\\\\sample.txt", True) 
	End If 
Catch ex As Exception 
	MsgBox(ex.Message, MsgBoxStyle.OkOnly + MsgBoxStyle.Critical, "エラー") 
End Try 


_________________
囚人のジレンマな日々
unibon
ぬし
会議室デビュー日: 2002/08/22
投稿数: 1532
お住まい・勤務地: 美人谷        良回答(20pt)
投稿日時: 2006-03-10 08:55
引用:

Morleyさんの書き込み (2006-03-10 00:15) より:
些細なことなのですけど、
ファイルをコピーする場合、
Try-Catchで例外をキャッチする処理か、
元ファイルが存在するかチェックしてから処理するほうか、
どちらがよいでしょうか?


コピーが成功するための条件のひとつに、Exists しているがあるわけであり、それ以外にもコピーには必要な条件があります。たとえば、コピー先に対する書き込み権限があるかなど。
だから、Exists だけ検査するのも、一部の条件しか検査しないことになるので、私だったら [例1] にします。
また、Exists で検査に成功してから、Copy するまでのわずかな瞬間にファイルが消されてしまう可能性もあり、どうしても抜けが残ります。これも、やっぱり検査が完全ではないことになりますので [例1] にしたい理由になります。

しかし、(私は System.IO.File.Copy は使ったことはないのですが、) API によっては処理に失敗した時に、中途半端な状態が残ることがあります。ファイル関係だったらたとえば0バイトのファイルができるとか等です(System.IO.File.Copy がどういう仕様かは知りませんが)。そういう場合は、失敗した後からの復旧が面倒になるので、Exists 等での事前検査は有意義でしょう。
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2006-03-10 09:19
余計なことをするメソッドですか...
まあ、列挙体で何が理由でコピーできなかったのかを返せばまだマシですが。

コード:

    Public Shared Function CopyFile(ByVal sourcePath As String, ByVal destPath As String, ByVal overwrite As Boolean) As Boolean
        If Not System.IO.File.Exists(sourcePath) Then
            Return False
        End If

        If System.IO.File.Exists(destPath) Then
            If Not overwrite Then
                Return False
            End If

            If (System.IO.File.GetAttributes(destPath) And System.IO.FileAttributes.ReadOnly) = System.IO.FileAttributes.ReadOnly Then
                Return False
            End If
        End If

        Try
            System.IO.File.Copy(sourcePath, destPath, overwrite)
        Catch ex As System.IO.IOException
            Throw ex
        End Try
    End Function


関係ないですけど、MsgBox のパラメタの結合は + ではなく Or が正しいです。
Option Strict On にしておきましょう。

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
Morley
会議室デビュー日: 2003/02/27
投稿数: 18
投稿日時: 2006-03-10 14:15
皆さんありがとうございました。
これらを参考に一つ一つ実装してみたいと思います。

引用:


関係ないですけど、MsgBox のパラメタの結合は + ではなく Or が正しいです。
Option Strict On にしておきましょう。




そうなんですか?「かんたんプログラミングVisual Basic.NET基礎編」
の166ページには + で結合するように例が書いてありました(笑)

じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2006-03-10 14:34
引用:

Morleyさんの書き込み (2006-03-10 14:15) より:

そうなんですか?「かんたんプログラミングVisual Basic.NET基礎編」
の166ページには + で結合するように例が書いてありました(笑)


+ で結合すると System.Int32 になります。
列挙体の型ではなくなるわけです。
実際にウォッチ式で型を見ると良いでしょう。

Option Strict On の状態だと多分怒られます。

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
なちゃ
ぬし
会議室デビュー日: 2003/06/11
投稿数: 872
投稿日時: 2006-03-10 16:31
引用:

じゃんぬねっとさんの書き込み (2006-03-10 09:19) より:
コード:
        Try
            System.IO.File.Copy(sourcePath, destPath, overwrite)
        Catch ex As System.IO.IOException
            Throw ex
        End Try




素朴な疑問。
なんでわざわざキャッチしてからスローするんでせうか?
※ここでは単にこの例外が起きる可能性があるのでっていうか、
 まあ、話の流れからなんとなく気分は分かるんですけどね。

ただ、正直
Throw ex
はやめたほうがいいと思うので。
※特別に理由がある場合は別ですが。

引用:

関係ないですけど、MsgBox のパラメタの結合は + ではなく Or が正しいです。
Option Strict On にしておきましょう。


あと、たいていの場合で出てくるような値の範囲では、普通問題は起こりませんが、
本来ビット演算を行いたい意図のあるところで、加算をするのはおかしいってことですね。

加算とビット演算は、この例ではたまたま同じ結果になるだけであって、
もともと別のことを実行する演算です。
※分かってる人にとっては、特定の条件内で実際に問題は発生しないことが
 明らかであっても、意味が異なることはやるべきではありません。

っていうかまあ、書籍に書いてあったんなら、そっちがまずいんですけどね。
まあひょっとしてら補足とかはあるのかもしれませんが。
うにくま
ベテラン
会議室デビュー日: 2005/11/05
投稿数: 82
投稿日時: 2006-03-10 16:35
本題から外れますが、
"+"と"Or"は同じ動作のようで実は違います。

DrawItemState列挙体を例にして説明します。
以下のようなメソッドがあったとして、
コード:
    Private Function PlusOperator(ByVal state As DrawItemState) As DrawItemState
        PlusOperator = state + DrawItemState.Grayed
    End Function

    Private Function OrOperator(ByVal state As DrawItemState) As DrawItemState
        OrOperator = state Or DrawItemState.Grayed
    End Function


引数stateの内容が DrawItemState.Selected だった場合、
結果は両方とも "Selected, Grayed" となりますが、

引数stateの内容が DrawItemState.Grayed だった場合、
OrOperatorは"Grayed"(期待する結果)
PlusOperatorは"Disabled"(期待しない結果)
と異なります。

"Or"は指定したビット以外は影響ありませんが、
"+"では他のビットにも影響を与えます。("-"も同様です)

スキルアップ/キャリアアップ(JOB@IT)