C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[10]: フォルダ移動中にフォルダを移動したくない


(過去ログ 171 を表示中)

[トピック内 12 記事 (1 - 12 表示)]  << 0 >>

■98761 / inTopicNo.1)  フォルダ移動中にフォルダを移動したくない
  
□投稿者/ 信号機 (1回)-(2021/12/22(Wed) 08:26:15)

分類:[VB.NET/VB2005 以降] 

VB.NET(Win7pro)で、
作業者がフォルダを手動で入れたものを、フォーム上で選択したうえで別フォルダに移動するプログラムを作っています。
そのまま移動するだけなら簡単かもしれませんが、
作業者が移動中で全部移動しきっていない状態で移動してしまうのが怖いので、何かいい方法がありましたらご教授頂けたらと思います。

自分なりに調べてみると、操作中はフォルダ名を変更できないことを利用してフォルダ名変更を試みる、というものはあったのですが
手動で実験してみた結果、確かに変更出来ない時もありましたが変更でき時もありましたので(多分ファイル移動の境目?)
この方法は使えませんでした。

また、たまに1GB-3GB程の重たいフォルダもありますので
フォルダ容量を数回監視して違いをみるというものも極力避けたいです(フォルダ容量を調べると時間かかるらしいので)
引用返信 編集キー/
■98762 / inTopicNo.2)  Re[1]: フォルダ移動中にフォルダを移動したくない
□投稿者/ くま (93回)-(2021/12/22(Wed) 09:11:07)
作業者とフォームを動かしている人が別なら

【VB.NET】フォルダのアクセス権限を変更する
http://blog.livedoor.jp/akf0/archives/51465466.html

でアクセス権限を変更して他の人が変更できなくすればよいのでは?

あとは
ファイルをロック(アクセスを制限)する
https://dobon.net/vb/dotnet/file/fileshare.html

で対象をすべて一度ロックしてしまうとか?
どっちにしても処理終了や中断で状態を元に戻すのが大変そうだけど。
引用返信 編集キー/
■98763 / inTopicNo.3)  Re[2]: フォルダ移動中にフォルダを移動したくない
□投稿者/ くま (94回)-(2021/12/22(Wed) 09:16:29)
追加
後実行前に、フォルダ属性で「隠し属性」を設定するとか

フォルダの属性を取得、設定する
https://dobon.net/vb/dotnet/file/directoryattributes.html
引用返信 編集キー/
■98764 / inTopicNo.4)  Re[2]: フォルダ移動中にフォルダを移動したくない
□投稿者/ 信号機 (3回)-(2021/12/22(Wed) 09:31:02)
くまさん、ありがとうございます。
ファイルのロックができることは知りませんでした、勉強になります。

作業者はメインのフォルダの中にAを移動して、終わったらメインフォルダにBを移動して....という作業を繰り返しており、1度移動したAをメインフォルダ外へ出すということはしませんので、そこの心配は不要かなと思っています。
また、メインフォルダに制限をかけるのも作業者が他の作業中だと困るので出来かねます。

Aをメインフォルダに移動中にプログラム側が移動しようとするのを回避したいので、フォルダが移動中という判定か、フォルダ内部が何も変わっていないという判定か、フォルダを誰も触っていないという判定の方法が知りたいです。
引用返信 編集キー/
■98765 / inTopicNo.5)  Re[3]: フォルダ移動中にフォルダを移動したくない
□投稿者/ くま (95回)-(2021/12/22(Wed) 10:17:31)
2021/12/22(Wed) 10:18:51 編集(投稿者)

まず一応書いておきます

フォルダ、ファイルの変更を監視する
https://dobon.net/vb/dotnet/file/filesystemwatcher.html

> Aをメインフォルダに移動中にプログラム側が移動しようとするのを回避
まずどうやってその「メインフォルダのAというファイル」が存在するのかを確認するのかわかりませんが

ファイルサイズを取得する
https://dobon.net/vb/dotnet/file/filesize.html

時間を空けてサイズを確認するか、ファイルの更新日時で確認

普通ファイル書き込み中はロックがかかっているはずですから
ファイルをロック(アクセスを制限)するの逆で
「ファイルがロックされているか」を時間を空けて確認するかの方法かと思います。

普通ファイルが書き込まれている途中はアクセスできないはずだから移動させようとしたときにエラーになるはずだけど...?

気になるなら簡単にはファイルの更新日時で現在の時刻よりxx分以内のファイルは移動対象外とするとかかな?
(確認時refreshするの忘れないでね)

引用返信 編集キー/
■98766 / inTopicNo.6)  Re[4]: フォルダ移動中にフォルダを移動したくない
□投稿者/ くま (96回)-(2021/12/22(Wed) 10:31:11)
一応
ファイルのタイムスタンプ(作成日時、更新日時、アクセス日時)を取得、設定する
https://dobon.net/vb/dotnet/file/filetimestamp.html

あと一応「隠し属性」はファイルを隠すだけではなく「処理中」なんかの意味で使ったりもします。
例えば信号機 さんのプログラムが移動対象としたファイルを「隠し属性」にしてから移動しているとします。
電源が急に落ちてPCが遮断された場合「隠し属性」にしておけば「ファイルが移動中に処理が止まった」事が分かります。

引用返信 編集キー/
■98767 / inTopicNo.7)  Re[5]: フォルダ移動中にフォルダを移動したくない
□投稿者/ くま (97回)-(2021/12/22(Wed) 11:03:20)
2021/12/22(Wed) 11:07:53 編集(投稿者)

もう少し詳しく書くと
信号機 さんのプログラムが[フォルダA]の中身を移動させたい時点で
[フォルダA]
 [ファイル1]←移動済み
 [ファイル2]←移動中[ファイル2]
       ←移動待ち[ファイル3]
この様な状態が考えられるでしょ?
その場合「一定期間を空けて、フォルダの状態を比較」しないと[フォルダA]が
「もう変更が済んだ」状態かはわからないわけです。
よって「時間を空けて確認する」必要があるわけです。

でさらに「プログラムがファイルAの中身を移動中に変更される事」も防止しないといけない。
そういう場合「移動開始時」

[フォルダA_GUID]←[フォルダA]の名前を変更して「隠し属性」を設定。GUID部分は下のURL参考に
[フォルダA]←新規に作成

こんな感じにすれば一瞬で[フォルダA]の状態は保持されます。

GUID値を生成するには?[C#、VB]
https://atmarkit.itmedia.co.jp/fdotnet/dotnettips/675generateguid/generateguid.html

そういう意味で「操作中はフォルダ名を変更できないことを利用してフォルダ名変更を試みる」は一つの方法として有効でしょうね。
引用返信 編集キー/
■98768 / inTopicNo.8)  Re[6]: フォルダ移動中にフォルダを移動したくない
□投稿者/ くま (99回)-(2021/12/22(Wed) 11:47:30)
> フォルダ容量を数回監視して違いをみるというものも極力避けたいです(フォルダ容量を調べると時間かかるらしいので)
一応書いておくと「フォルダ」にもアクセス日時と更新日時あるからね
System.IO.Directory.GetLastWriteTime("D:\フォルダ")

「フォルダ」に書き込み開始、リネーム、削除されたタイミングで更新されます。
ただし「フォルダ」含まれているファイルが更新されても、「フォルダ」下位フォルダ内に変更があっても更新されません。

なので
1. フォルダの更新日時で変更がないか確認
2. ファイルの更新日時で変更がないか確認
3. 違いがあった時点で確認停止

1. フォルダの更新日時で変更がないか確認
2. フォルダのリネームで変更できない場合、ファイルが書き込み中と判断

再帰処理と組み合わせだろうけど、そんなに遅くならないよ?
確認間隔も10秒は開けるだろうし...一度に何万件も処理するの?
引用返信 編集キー/
■98769 / inTopicNo.9)  Re[7]: フォルダ移動中にフォルダを移動したくない
□投稿者/ くま」 (1回)-(2021/12/22(Wed) 12:16:23)
2021/12/22(Wed) 12:16:44 編集(投稿者)

訂正
引用返信 編集キー/
■98770 / inTopicNo.10)  Re[8]: フォルダ移動中にフォルダを移動したくない
□投稿者/ くま (100回)-(2021/12/22(Wed) 12:19:10)
2021/12/22(Wed) 12:37:32 編集(投稿者)
※削除ファイルを考慮していなかったので処理追加
Module Module1
    Private checkPath As Dictionary(Of String, Date) = New Dictionary(Of String, Date)
    Public Sub ClserCheckPath()
        checkPath = New Dictionary(Of String, Date)
    End Sub
    Public Function StartCheckPath(path As String) As Boolean
        Dim IsChange As Boolean = False
        Dim temp As Dictionary(Of String, String) = New Dictionary(Of String, String)

        Dim di As New System.IO.DirectoryInfo(path)
        Dim files As System.IO.FileInfo() = di.GetFiles("*", System.IO.SearchOption.AllDirectories)
        For Each f As System.IO.FileInfo In files
            Dim fullPath As String = f.FullName
            f.Refresh()
            If checkPath.ContainsKey(fullPath) Then
                If checkPath(fullPath) <> f.LastWriteTime Then
                    checkPath(fullPath) = f.LastWriteTime
                    IsChange = True
                End If
            Else
                checkPath.Add(fullPath, f.LastWriteTime)
                IsChange = True
            End If
            temp.Add(fullPath, fullPath)
        Next
        '削除ファイル確認
        Dim keys() As String = checkPath.Keys.ToArray
        For Each key As String In keys
            If temp.ContainsKey(key) = False Then
                IsChange = True
                checkPath.Remove(key)
            End If
        Next
        Return IsChange
    End Function
End Module

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click

    Call ClserCheckPath()
    'ストップウォッチを開始する 
    Dim sw As New System.Diagnostics.Stopwatch()
    sw.Start()

    Debug.Print("{0}", StartCheckPath("D:\Test\"))

    'ストップウォッチを止め結果を表示する 
    sw.Stop()
    Debug.Print("{0}", sw.Elapsed)

    '一秒間(1000ミリ秒)停止するこの間に変更があるものとする
    System.Threading.Thread.Sleep(1000)

    sw.Start()

    Debug.Print("{0}", StartCheckPath("D:\Test\"))

    'ストップウォッチを止め結果を表示する 
    sw.Stop()
    Debug.Print("{0}", sw.Elapsed)
End Sub

引用返信 編集キー/
■98775 / inTopicNo.11)  Re[9]: フォルダ移動中にフォルダを移動したくない
□投稿者/ 信号機 (4回)-(2021/12/22(Wed) 20:02:45)
くまさん
なるほど!このIsChangeがFalseになるまで回せば、フォルダ内のファイルは変更がないということなんですね!
これとフォルダ名の変更を試みる方法を組み合わせてやってみます!
丁寧に教えて頂きありがとうございました!
解決済み
引用返信 編集キー/
■98780 / inTopicNo.12)  Re[10]: フォルダ移動中にフォルダを移動したくない
□投稿者/ くま (104回)-(2021/12/22(Wed) 23:25:00)
一度「解決済み」にしたのにゴメンネ
上の処理、先に書いた方法ではないです。
「あえて遅い方法で書いたけど、そんなに遅くならなかったよ」という意味なんで...。
(処理は正しいですが)
でもこの処理が例えばネットワーク超えた先にあるドライブで10秒かかったとします。
それはもう「確認するには必要なコスト」だと割り切るしかないです。
というのも結果として「ソフトでは埋まらない時間」がかかっているからです。
そこはご容赦ください。
解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -