Klasördeki Dosyaların Süresi Doldu: x Gün Sonrası Dosyaları Sil


12

Herkes tarafından erişilebilen bir windows paylaşılan sürücüde bir "Klasör Bırak" yapmak arıyorum. X günden fazla bir süre klasörde kalırlarsa dosyaların otomatik olarak silinmesini istiyorum.

Ancak, bunu yapmak için bulduğum tüm yöntemler gibi görünüyor, son değiştirilme tarihini, son erişim saatini veya bir dosyanın oluşturulma tarihini kullanıyorum.

Bu bir kullanıcının biriyle paylaşmak için dosyaları bırakabilirsiniz bir klasör yapmaya çalışıyorum. Birisi dosyaları kopyalar veya buraya taşırsa, saatin bu noktada işaretlemeye başlamasını isterim. Ancak, birisi dosyayı gerçekten değiştirmedikçe, dosyanın son değiştirilme tarihi ve oluşturma tarihi güncellenmez. Son erişim süresi çok sık güncellenir ... Görünüşe göre, Windows Gezgini'nde bir dizin açıldığında son erişim süresi güncellenir.

Buna bir çözüm bilen var mı? Günlük olarak dosyaların karma kataloglama ve daha sonra belirli bir tarihten daha eski karma dayalı dosyaları süresi biten bir çözüm olabilir düşünüyorum ... ama dosyaların karma alarak zaman alıcı olabilir.

Herhangi bir fikir büyük mutluluk duyacağız!

Not: Burada
zaten birçok cevaba baktım ... Dosya Sunucusu Kaynak İzleyicisi'ne, powershell komut dosyalarına, toplu komut dosyalarına vb. Baktım. Hala son erişim zamanını, son değiştirilme zamanını veya oluşturma zamanını kullanıyorlar ... tarif edildiği gibi, yukarıdaki ihtiyaçlara uymaz.


@Michael Kjorling'in belirttiği gibi bir soru, dosya kutuya bırakıldıktan sonra değiştirilirse zamanlayıcı saymayı durdurur mu?
Get-HomeByFiveOClock

Aradığınız şey Windows eşdeğeri tmpwatch.
Avery Payne

Yanıtlar:


5

Bir powershell betiği ve bir politika kombinasyonu kullandık. İlke, kullanıcının Drop_Zone paylaşımında bir klasör oluşturması ve ardından istediği dosyaları bu klasöre kopyalaması gerektiğini belirtir. Klasör 7 günlük olduğunda (CreationTime kullanılarak) powershell betiği dosyayı siler.

Ayrıca çalışmasını doğrulayabilmemiz için powershell betiğine bazı günlükler ekledim ve sadece kendilerinden tamamen inert kaydetmek için gölge kopyaları açtım.

İşte tüm günlükleri olmayan komut dosyası.

$location = Get-ChildItem \\foo.bar\Drop_Zone
$date = Get-Date
foreach ($item in $location) {
  # Check to see if this is the readme folder
  if($item.PsIsContainer -and $item.Name -ne '_ReadMe') {
    $itemAge = ((Get-Date) - $item.CreationTime).Days
    if($itemAge -gt 7) {
      Remove-Item $item.FullName -recurse -force
    }
  }
  else {
  # must be a file
  # you can check age and delete based on that or just delete regardless
  # because they didn't follow the policy
  }
}

1
Bu en basit görünüyor, dosya tarih damgası, alternatif veri akışları ile dolmuyor veya bazı dosyalar ve bırakma tarihleri ​​listesi gerektirmiyor. Her türlü büyüyü yapan harika bir senaryo oluşturacaktım, ama sonra bunu gördüm.
BeowulfNode42

ve betiği her zaman tetikleyen bir dosya sistemi izleme olayı gerektirmez, çünkü günde bir kez çalıştırılabilir ve herhangi bir nedenden dolayı bir günün kaçırılması o kadar da önemli değildir.
BeowulfNode42

2
Büyük basit bir fikir, tıpkı @ BeowulfNode42'nin işaret ettiği gibi. Kullanıcıların bir klasör oluşturmaları gerektiğinden emin olmak için "Dosya Oluştur / Veri Yaz" ACL'sinin "Yalnızca Bu Klasör" e basit bir "Reddet" seçeneği, kullanıcıların da alt klasörler oluşturmasını sağlar.
Brett G

3

NTFS olduğunu varsayabilirseniz, dosyanın alternatif akışına bir anahtar (Guid) yazabilirsiniz. Artı tarih, böylece temelde veritabanında dosyaları saklamak.

Daha fazla bilgi için:

http://blogs.technet.com/b/askcore/archive/2013/03/24/alternate-data-streams-in-ntfs.aspx

Temel olarak, özel bir adla kodlanmış ayrı bir akışta ek içerik depolayabilirsiniz.


Bunu nasıl yaparsınız?
Brett G

@BrettG Belgelere bağlantı eklendi. "NTFS Alternatif Veri Akışı", her ihtimale karşı Google'da da bulunmanızı sağlardı - Google'ı bilmiyorsunuz.
TomTom

Üzgünüz, alternatif veri akışlarının ne olduğunu biliyorum, sadece bu bağlamda kullanımlarını anlamaya çalışıyordum. Yani bir karma veya başka bir şey kullanmak yerine, dosyaları izlemek için alternatif veri akışında bir GUID (ve / veya tarih) kullanın.
Brett G

Evet. Bir dosyayı güvenilir bir şekilde İŞARETLEYEBİLİRSİNİZ - hatta işaretleme tarihini koyabilirsiniz - o zaman bir karma hesaplamanıza gerek yoktur.
TomTom

Bir dosyanın mağazadan kopyalanıp kopyalanmadığına, düzenlenip kopyalanıp tekrarlanmadığına dikkat edin. Daha sonra bir karma yararlı olabilecek zamanlayıcıyı yeniden başlatmak istersiniz.
CVn

2

Oluşturulan yeni dosyalar için bir klasörü "izlemenize" izin veren IO.FileSystemWatcher kullanabilirsiniz. İşte bu işi yapmak için ihtiyacınız olan parçalar.

Bu değişkenler, izlenecek yolu ve hangi dosyaların izleneceğini ayarlamak için bir filtre yapılandırır:

$watchFolderPath = $env:USERPROFILE
$watchFolderFilter = "*.*"

Bu, izlenecek klasörün parametrelerini ve olay gerçekleştiğinde gerçekleştirilecek eylemleri ayarlar. Temel olarak bu, her dosyadaki LastWriteTime'ı yazıldığı gibi sıfırlar:

$watcher = New-Object IO.FileSystemWatcher $watchFolderPath, $watchFolderFilter -Property @{
    IncludeSubdirectories = $true
    NotifyFilter = [IO.NotifyFilters]'FileName, LastWrite'
    }
$onCreated = Register-ObjectEvent $watcher Created -SourceIdentifier FileCreated -Action {
    $FileName = $Event.SourceEventArgs.FullPath
    $file = Get-Item $FileName
    $file.LastWriteTime = Get-Date
    }

Etkinlik, aşağıdakiler kullanılarak gerekirse kaydedilebilir:

Unregister-Event -SourceIdentifier FileCreated

Son olarak, eski dosyaları temizlemek için bunu günde bir kez çalıştırabilirsiniz:

Get-ChildItem $watchFolderPath -Recurse | Where-Object {((Get-Date)-$_.LastWriteTime).TotalDays -gt 6} | Remove-Item

İhtiyacınız olan her şey bu olmalı ...


Dosya oluşturulduğunda LastWriteTime özniteliğini ayarlamak ve daha sonra dosyaları daha sonra silmek için bunu düzenlemek için bunu düzenleyin.
Tim Ferrill

1

Bir süredir ama bunu ele almak için nispeten düz bir yöntem ayarladım.

Bırakma dizinine eklenen herhangi bir dosyaya (kaynak izleme yardımcı programı aracılığıyla izlenir) dokunur ve klasöre eklenen tarihe son değiştirilme tarihini ayarlarım.

Daha sonra yaşlanması gereken dosyaları temizlemek için son değiştirilme tarihini kullanabilirim. Bu, birisinin dosyayı gerçekten güncellemesi durumunda geri sayımı sıfırlayacağı avantajına da sahiptir.


Mükemmel bir fikir. Kendi araştırmamı yapacağım .. ama hangi kaynak izleme yardımcı programını kullandığınızı biliyor musunuz?
Brett G

@BrettG dürüst olmak gerekirse yaklaşık 10 yıl önceydi. Hatırlayamıyorum. Beni yaşlı hissettiriyorsun. :) Bugün yapsaydım, olay görüntüleyicideki dosya sistemi denetim olaylarına dayalı bir iş yürütürdüm. FileSystemWatcher .NET nesnesinin PowerShell üzerinden kullanılabileceğini düşünüyorum. Başka bir seçenek olurdu.
Tim Brigham

Ha, "bir süre" dediğinde bu kadar uzun sürdüğünü fark etmedim. Evet yeterince komikti sadece FileSystemWatcher'a bakıyordum. Yine de, taşınan / kopyalanan dosyalarla çalışacağını sanmıyorum. Cevap için teşekkürler!
Brett G

1
@BrettG - Filesystemwatcher bir izleme tablosu ile birlikte kullanılabilir, ancak kendi sorunları vardır. Buraya bakın: stackoverflow.com/questions/1764809/… stackoverflow.com/questions/6000856/filesystemwatcher-issues
JohnP

1
@BrettG - Ayrıca, bu FSW için iyi bir uzantı: codeproject.com/Articles/58740/…
JohnP

1

Bir dosyanın kopyalandığı veya bir klasöre taşındığı tarihlere güvenmenin bir yolu yoktur. Windows dosya sistemlerinde, sürücülerde, ağ paylaşımlarında vb. Bunları korumayı başarır. Bir linux dosya sunucusunda bir şeyler yapabilir veya insanların FTP veya web tabanlı bir yükleme sistemi kullanarak dosyaları doğrudan kopyalamasını engelleyebilirsiniz.

İnsanların dosyaları yükledikten sonra değiştirememeleri konusunda sorun yaşıyorsanız, ayrı yükleme ve erişim klasörleriniz ve dosyaları bunlar arasında taşıyarak yeniden tarihlendiren bir komut dosyanız olabilir. Ancak, insanların dosyaları doğrudan değiştirmesini istediğiniz gibi görünüyor.

Yani basit, eğer biraz huysuzsa, tarihlerle uğraşmak olacaktır. İki senaryo yazardım:

Saatlik Tarih Değiştirici komut dosyası

Bir betiğin saatte bir kez, tercih ettiğiniz dilde çalıştırılmasını sağlayın:

  • Son 20 yıl içinde değiştirilmiş bir dosyaya bakar.
  • Böyle bir dosyayı bulduğunda, değiştirildiği tarihi bugün eksi 20 yıl olarak değiştirin.

Powershell'de şöyle görünecektir:

$path = "D:\test"

$today = Get-Date
$before = $today.AddDays(-7300) #356*20 days

Get-ChildItem -Recurse -Path $path | foreach {
    if ($_.LastWriteTime -gt $before) {
        Write-Host $_.Name
        $_.LastWriteTime = $before
    }
}

Bu komut dosyasını bugün (27 Mayıs) çalıştırmak, tüm dosyaların değiştirilme tarihini 1 Haziran 1994'e ayarlar - tam olarak 356 * 20 gün önce. Yalnızca $ önce değerinden daha yeni dosyaları değiştirdiği için geçmişte ayarlamış olduğu dosyalara dokunmaz.

Temizleme Betiği

Temizleme betiği her gece çalışır ve:

  • Değiştirilme tarihi "20 yıl ve X gün önce" olan dosyaları ara
  • Onları sil

Bu bölüm için komut dosyası yazmam - belirli bir tarihten daha eski dosyaları silmeyi başarabilecek birçok yardımcı program var, hangisini seçerseniz seçin. Önemli olan 7300 + X günlük dosyaları aramaktır, burada X en son değiştirilmelerinden bu yana saklamak istediğiniz gün sayısıdır.

Avantajları

Bunun diğer cevaplara göre birkaç avantajı vardır:

  • Birisi dosyayı değiştirirse zamanlayıcı sıfırlanır.
  • Dosyaları işaretlemek için NTFS alternatif akışlarına gerek yoktur (dosya taşınırken korunur, bu nedenle değiştirilen dosyanın erken silinmesine neden olabilir)
  • Herhangi bir performans etkisi varsa minimum düzeyde olmalıdır. Bir veritabanı veya dosya adları ve / veya karma listesi tutmaya gerek yoktur.
  • Komut dosyaları çalıştırılamazsa hiçbir şey korkunç şekilde kırılmaz. Tarihi güncellemek için servis veya sürekli çalışan bir program gerekmez. Sadece birkaç zamanlanmış görev. Yeni dosyaları izlemeye ve son değiştirilme zamanlarını şu an için güncellemeye dayanan çözümler, hizmet başarısız olursa veya yarış durumuna girerse yeni dosyaları silebilir.

Görebildiğim tek sorun, insanların en son 20 yıl önce değiştirilmiş bir dosyayı açılan klasöre kopyalayıp kopyalamaması. Bence çoğu senaryoda, bu çok fazla bir sorun değildir, ancak ortaya çıkabilir.


0

"Upload" IFRAME olan bir web sayfası aracılığıyla açılır kutuya dosya eklemeyi resmileştirebilirsiniz. Kullanıcı daha sonra dosyayı bir PHP / ASP işini çağıran dosyayı "gönderebilir", bu dosyayı alır ve büzülme konumuna yerleştirir. PHP / ASP herhangi bir sayıda indeks / analiz işlemi yapabilir.


0

Birisi dosyaları kopyalar veya buraya taşırsa, saatin bu noktada işaretlemeye başlamasını isterim. Ancak, birisi dosyayı gerçekten değiştirmedikçe, dosyanın son değiştirilme tarihi ve oluşturma tarihi güncellenmez.

Her beş dakikada bir zamanlanmış görevler olarak çalışan ve iki şey yapan bir komut dosyası oluştururdum.

  1. İlk eylem, klasöre kopyalanan herhangi bir dosyanın kopyasını oluşturur, dosyaya bir önek koyar ve orijinali siler. Bu, dosyanın oluşturulma tarihinin uygulama için aynı olmasını sağlar.
  2. İkinci eylem, önceden belirlenmiş öneki (eylem 1 ile ayarlanır) olan tüm dosyalara bakar ve oluşturulma tarihi X günden daha eski olan dosyaları siler. Bu, değişiklik / erişilen tarih sorununu çözecektir.

0

Dosyaları işaretlemek için mevcut bir mekanizma var, Arşiv biti. DOS'un ilk günlerinden beri orada ve hem FAT hem de NTFS'de mevcut.

Temel olarak, her dosya varsayılan olarak arşiv bitine sahip olacaktır. Bir dosyayı görürseniz ile sizin damla klasöründe arşiv bit, (1) bu bit ve (2) bugün kendi tarihini ayarlamak temizleyin. Bir dosyayı görürseniz olmadan o bit ve tarih <= geçmişte 7 gün ile silin.

Bir kullanıcı dosyaya bırakma klasöründe yazarsa, arşiv biti yeniden ayarlanır, böylece kullanım ömrü de 7 güne sıfırlanır. Sonuçta, yeni bir dosya.

Artık FileSystemWatcher'ı güvenle kullanabilirsiniz. İlgili bilgilerin tümü dosya meta verilerinde bulunduğundan, sahip olduğu sorunların (yinelenen etkinlikler, arabellek taşması ayrıntılı bilgilerini kaybetmesi gibi) artık önemi yoktur.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.