Windows'da çok sayıda dosya nasıl silinir


22

Milyonlarca alt dizin ve trilyonlarca dosya içeren bir dizin var. Ve şimdi temizlemeliyim. Trilyon diyorum, dosya boyutundan değil, dosya sayısından bahsediyorum.

Silmeyi del/sve Windows Gezgini'ni kullanmayı denedim . İkisi de görevi tamamlayamaz. Bazı alt dizinleri birer birer silmeyi denedim ve bu bana günler sürdü. Karşılaştığım sorun, delExplorer veya Explorer ne olursa olsun, her seferinde Görev Yöneticisi'nde explorer örneğinin gök yüksekliğinde bellek tükettiğini ve yavaş yavaş sistemimi çökmeye zorladığını görebiliyordum.

Silinecek yüz milyonlarca dosya var. Bir (veya sadece birkaç) komutla / eylemle gerçekleştirme olasılığı var mı?


[REDAKTE]

Cygwin ile yapmayı denedim rm -frve aynı sonucu verdim . Şu şekilde özetlenir:

  1. Windows Gezgini ne olursa olsun, DELkomut isteminden veya Cygwin rmkomutundan, Sistem belleği yavaş yavaş sıfıra düşer ve kutu sonunda çökecektir.

  2. Herhangi bir noktada, sistem başarısız olmadan önce işlem kapatılır (CTRL + C veya başka bir şeyle), kutu normal şekilde çalışmaya devam eder. Ancak, kullanılan tüm bellek boşaltılmaz. Diyelim ki sistem belleği% 91'e ulaşırken işlemi durduruyorum, Görev Yöneticisi şunu söylüyor: Toplamda 4G RAM, Önbellek 329M ve Kullanılabilir 335MB. Daha sonra makineyi yeniden başlatana kadar bellek kullanımı bu seviyede kalır. Görev Yöneticisi'nde explorer örneğini durdurursam, ekran sabit disk sürücüsü ışığı sürekli yanar ve hiçbir zaman geri gelmez. Normalde, Görev Yöneticisi'nde explorer örneğini durdurduğumda, Win + E tuşlarına basarak yeniden başlatabilirim veya otomatik olarak yeniden başlatıldı.

Gerçekten güzel bir hafıza yönetimi!


[TEKRAR DÜZENLE] Kullanılan belleğin bir kısmı uzun bir süre sonra serbest bırakılmış gibi görünüyor, ama hepsi değil. Önbelleğe Alınmış ve Kullanılabilir belleklerden bazıları Görev Yöneticisi'ne geri döndü. Artık beklemedim, o zaman ne olacağından emin değilim.


Yani asıl sorun, dizinlerin ve alt dizinlerin silinmemesidir.
Sandeep Bansal

@Jackey Cheung: Hangi pencereleri kullanıyorsunuz?
Siva Charan

1
Dosyaları en üst düzeyden başlayarak değil, örneğin klasör yapısının beşinci düzeyinde yeniden silen toplu bir komut dosyası yazabilirsiniz. Bu, işi birçok ayrı ve ardışık '

9
Bilmeliyim, gerçekten nasıl bir trilyon dosya aldın, gerçekten ...
Moab

2
Bir trilyon dosya için 1 PB olan bir dosya tablosu gerekir. Günümüzde en büyük sabit diskler birkaç TB. Bu kadar büyük bir bölümü nasıl elde ettiniz?
user541686

Yanıtlar:


10

Teknik Açıklama

Çoğu yöntemin sorunlara neden olmasının nedeni, Windows'un dosya ve klasörleri numaralandırmaya çalışmasıdır. Bu, birkaç yüz derinlikteki birkaç yüz veya hatta bin dosya / klasörle ilgili bir sorun değildir, ancak milyonlarca klasörde düzinelerce seviyeye inen trilyonlarca dosyaya sahip olduğunuzda, bu kesinlikle sistemi bozacaktır .

"Yalnızca" 100.000.000 dosyanız var ve Windows, her dosyayı yoluyla birlikte depolamak için böyle basit bir yapı kullanıyor (bu şekilde her dizini ayrı ayrı depolamaktan kaçınıyorsunuz, böylece bir miktar ek yük kaydediyorsunuz):

struct FILELIST {                   // Total size is 264 to 528 bytes:
  TCHAR         name[MAX_PATH];     // MAX_PATH=260; TCHAR=1 or 2 bytes
  FILELIST*     nextfile;           // Pointers are 4 bytes for 32-bit and 8 for 64-bit
}

8-bit karakterler mi yoksa Unicode karakterler mi (Unicode kullanıyor) ve sisteminizin 32 bit mi yoksa 64 bit mi olduğuna bağlı olarak, listeyi saklamak için 25 GB ile 49 GB arasında bellek gerekir (ve bu çok çok basitleştirilmiş yapı).

Sebebi neden , Windows onları silmeden önce dosya ve klasörleri numaralandırmaya çalışır Bunları silmek için kullandığınız yönteme bağlı olarak değişir, ancak her iki Explorer ve komut yorumlayıcı (komutunu başlatırken bir gecikme görebilir) bunu. Disk etkinliğini (HDD LED'i), dizin ağacını sürücüden okurken de görebilirsiniz.

Çözüm

Bu tür bir durumla başa çıkmanın en iyi yolu, dosyaları ve klasörleri teker teker silen bir silme aracı kullanmaktır. Bunu yapmak için hazır herhangi bir araç olup olmadığını bilmiyorum, ancak basit bir toplu iş dosyasıyla başarmak mümkün olmalıdır .

@echo off
if not [%1]==[] cd /d %1
del /q *
for /d %%i in (*) do call %0 "%%i"

Bunun yaptığı bir argümanın iletilip iletilmediğini kontrol etmektir. Öyleyse, belirtilen dizine dönüşür (geçerli dizinde başlamak için bağımsız değişken olmadan çalıştırabilir veya orada başlamak için farklı bir sürücüde bile bir dizin belirtebilirsiniz).

Ardından, geçerli dizindeki tüm dosyaları siler. Bu modda, hiçbir şey numaralandırmamalı ve çok fazla bellek tüketmeden dosyaları silmemelidir.

Daha sonra geçerli dizindeki klasörleri numaralandırır ve kendisini çağırır, her klasörü aşağı doğru geri almak için kendisine (kendinden) geçirir.

analiz

Bu nedeni olmalı bunun içinde her bir dosya ve klasörü numaralandırmaz için işe olan tüm ağacı . Hiçbir dosyayı numaralandırmaz ve yalnızca geçerli dizindeki klasörleri (ayrıca üst dizinlerde kalan klasörleri) numaralandırır . Herhangi bir klasörde sadece birkaç yüz alt dizin olduğunu varsayarsak, bu çok kötü olmamalıdır ve kesinlikle tüm ağacı numaralandıran diğer yöntemlerden çok daha az bellek gerektirir.

/r(Manuel) özyineleme kullanmak yerine anahtarı kullanmayı merak edebilirsiniz . Bu işe yaramaz çünkü /ranahtar özyineleme yaparken , tam olarak kaçınmak istediğimiz şey olan dizin ağacını önceden numaralandırır; takip etmeden giderken silmek istiyoruz.

karşılaştırma

Bu yöntemi tam numaralandırma yöntem (ler) i ile karşılaştıralım.

“Milyonlarca dizininiz” olduğunu söylemiştiniz; diyelim 100 milyon. Ağaç yaklaşık olarak dengeliyse ve klasör başına ortalama yaklaşık 100 alt dizin varsayarsa, en derin iç içe dizin yaklaşık dört düzey aşağı olur - aslında, tüm ağaçta 101,010,100 alt klasör olur. (100M'in sadece 100 ve 4'e nasıl ayrılabileceğini eğlendirmek.)

Dosyaları numaralandırmadığımız için, 4 × 100 = 400belirli bir zamanda en fazla dizin için seviye başına yalnızca en fazla 100 dizin adını izlememiz gerekir .

Bu nedenle, bellek gereksinimi ~ 206.25KB, herhangi bir modern (veya başka) sistem sınırları dahilinde olmalıdır.

Ölçek

Ne yazık ki (?) Milyonlarca klasörde trilyonlarca dosyaya sahip bir sistemim yok, bu yüzden test edemiyorum (son sayımda inanıyorum, yaklaşık ~ 800K dosyam vardı), bu yüzden başka biri denemek zorunda kalacak o.

Uyarı

Elbette bellek tek sınırlama değildir. Sildiğiniz her dosya ve klasör için sistemin boş olarak işaretlemesi gerektiğinden sürücü de büyük bir darboğaz olacaktır. Neyse ki, bu disk işlemlerinin birçoğu birlikte paketlenecek (önbelleğe alınacak) ve ayrı ayrı yerine parçalar halinde yazılacak (en azından sabit diskler için, çıkarılabilir medya için değil), ancak sistem okurken yine de biraz dayalanmaya neden olacak ve verileri yazar.


Eminim bu işe yaramıyor. Denedim. Sorun FOR döngüsünde yatmaktadır. FOR'nun doğrudan DEL yayınlamakla aynı soruna neden olacağı ortaya çıktı.
Jackey Cheung

1
Kullandığınız anahtarlara bağlıdır. /rAnahtarı kullandıysanız, açıkladığım gibi, tüm dosyaları numaralandırmaya çalışır. /dAnahtarı kullanırsanız, yalnızca geçerli dizindeki klasörleri numaralandırır, bu nedenle geçerli dizinde bir milyar klasör yoksa, soruna neden olmamalıdır.
Synetech

7

Trilyonlarca dosyayla konuşamıyorum, ancak son zamanlarda ~ 1.8M dosyaları içeren eski bir dosya paylaşımını nuked kullanarak:

robocopy EmptyTMPFolder FolderToDelete /MIR /MT:16 /ETA /R:30 /W:5

"EmptyTMPFolder" boş bir yerel dizindir. / MIR seçeneği, hedefi kaynak (boş) gibi gösterecektir.

Bu yaklaşımın gerçek yararı yeniden deneme seçeneğiydi (/ R: 30). Bu, bu işlem sırasında oluşabilecek bağlantı sorunlarını özme fırsatı verdi. Yerel silmeler bu yaklaşımda fayda bulamayabilir.

Ben zaman karşılaştırmak için belirli bir kriter yok, ama ben denemek / beklemek seçenekleri b / c önerilen diğer seçeneklerin bazılarına tercih ederim. Silinmeler anında başladı.


Temizliği büyük bir ağ sürücüsü klasör ağacında çalıştırırken bunun en etkili yöntem olduğunu buldum. Bahşiş için teşekkür ederim.
Tonny

5

Tüm klasörleri silmek uzun zaman alacaktır ve bu konuda yapabileceğiniz çok fazla bir şey yoktur. Yapabileceğiniz şey verilerinizi kaydetmek ve sürücünüzü biçimlendirmektir. Optimal değildir, ancak çalışır (ve hızlı bir şekilde).

Başka bir seçenek de, bir NTFS bölümünden okuyabilen canlı bir CD'de bazı linux dağıtımını kullanmaktır. rm -rf folderName2GB RAM ile bir sistemi çökertmeden en az 2 gün çalışabilecek kişisel deneyimimden biliyorum . Biraz zaman alacak, ama en azından bitecek.


1
hm, Linux. Cygwin'i düşünüyorum. Altında yatan Windows işlevlerini kullanması gerekiyorsa da, sadece durumda herhangi bir fark yaratıp yaratmayacağını merak ediyor. Ben deneyeceğim.
Jackey Cheung

1
git bash
raindrop

4

Hmm .. Nasıl bu kadar çok yarattığınızı bilmek istemiyorum.

Olan şey, Explorer'ın her bir dosyayı numaralandırmaya ve bilgileri silmeye başlamadan önce bellekte depolamaya çalışmasıdır. Ve tabii ki çok fazla var.

Komutu denedin rmdir /smi? Numaralandırılmak üzere her bir dosyayı beklemek yerine dosyaları buldukları anda sildiği sürece işe yarayabilir.

Kaç alt dizin seviyesi var? Yalnızca bir tane veya düşük bir sayı varsa, manuel olarak geri dönen hızlı bir toplu iş dosyası işe yarayabilir.

Yine de herhangi bir yöntem biraz zaman alacaktır.


Tabii ki soandos'un yeniden biçimlendirme önerisinin yanı sıra. Bu hızlı olur, ancak bu sistem sürücünüzse Windows'u yeniden yüklemeniz gerekir.
Bob

Numaralandırmanın gerçekleşmesi gerektiğinden eminim, böylece program bir sonraki silme işlemini biliyor. rmdir, üstten başladıkları ve bir şekilde geçiş yapmaları gerektiği için dosyaları bulundukları gibi silemez. Tek soru ne kadar fazla bilgi depoladığıdır.
soandos

@soandos Explorer her dosyayı sayar . Bir DFS numaralandırma tarzı uygulayan bazı yöntem düşünüyordum: mümkün olduğunca bir dal aşağı gidiyor, bir dosya vurduğunda, geri gelmeden önce silmek. Başka bir deyişle, özyineleme, bu da ne rm -rfyapar. Bu en iyi göreceli olarak sığ dizin yapılarında işe yarar. Bunu yapıp rmdir /syapmadığından emin değilim . Bu should .
Bob

1
@JackeyCheung rmdir /?: /s Removes all directories and files in the specified directory in addition to the directory itself. Used to remove a directory tree.Başka bir deyişle, /sbayrak dosyaları da siler. Nasıl kullandın del? Ve evet, sadece rm -rfsoandos'un önerdiği gibi kullanmak daha iyi olabilir .
Bob

1
@JackeyCheung: Yanılıyorsun. Rmdir / s bayrağını verirseniz, dizinlerin yanı sıra dosyaları da siler.
Harry Johnston

4

Bunun gibi bir sorunun olası nedenlerinden biri, genellikle SAN ortamlarında bulunan ince sağlamadır. Bazı katı hal sürücüleri aynı sorunu sergileyebilir. Bu durumda, bu yapılandırma değişikliği sorununuzu çözebilir:

fsutil behavior set DisableDeleteNotify 1

Bu değişikliğin yarıiletken sürücülerdeki performansı etkileyebileceğini ve SAN sürücülerinin otomatik ve / veya manuel olarak yeniden başlatılmasını engelleyebileceğini unutmayın.


3

Shift+ DeleteGeri Dönüşüm Kutusu'nu atlar ve işleri önemli ölçüde hızlandırabilir.

Bu işe yaramazsa (uç durumlar), Hızlı Klasör Silgisi ve / veya Toplu Dizin Silgisi'ni deneyin


çok sayıda resim dosyasını silmeye çalıştığımda, evet normal DEL ile karşılaştırıldığında oldukça hızlıdır DEL, teşekkürler
V-SHY

3

Muhtemelen tüm belleği tüketen ve daha sonra sistemi çökerten antivirüs / antimalware yazılımınızdır.

Windows'un kendisi çok sayıda dosyayı silmede sorun yaşamıyor, ancak Microsoft dışındaki çoğu dosya sisteminde benzer bir işlemden kesinlikle daha yavaş.


Güzel nokta! Tabii ki bir göz atmaya değer.
Jackey Cheung

Virüsten koruma yazılımını kapattım ve bellek hala eskisi gibi yenildi.
Jackey Cheung

Antivirüsün kapatılması, işlem durdurulduktan sonra belleğin boşaltılmasına yardımcı olmaz.
Jackey Cheung

@JackeyCheung: Hangi antivirüs programı? Bazıları aslında tamamen kapanmıyor ...
Ben Voigt

2

Karşılaşabileceğiniz bir sorun, bir dosyayı / klasörü sildiğinizde dizinin sıkıştırılmamasıdır, bu nedenle içinde 1 milyon dosya bulunan bir klasörünüz varsa ve ilk 500k dosyasını sildiğinizde. Dizininizin başında, tüm amaçlarla boş olan bir ton blok vardır.

AMA, explorer ve bir komut istemi, orada bir dosya olması durumunda hala bu bloklara bakmak zorundadır. Yardımcı olabilecek bir şey, bir klasörü ağaçtan bir yerden sürücünün tabanından yeni bir klasöre "taşımak" ve ardından bu yeni klasörü silmektir. Klasörü taşımak yalnızca işaretçiyi klasöre taşır, böylece hızlı gitmeli ve altındaki tüm dosyaları sürücüdeki yeni alana taşımamalıdır.

Deneyebileceğiniz başka bir şey, bir grup dosyayı sildikten sonra Compact klasörlerine "PerfectDisk" gibi bir üçüncü taraf aracı kullanmaktır.


2

10 milyondan fazla füzyon günlük dosyasını silmek için çeşitli yaklaşımlar denerken, ortalama 30 bin dosyanın 10 dakikalık bir süre içinde silinebileceğini fark ettim. 10 milyon dosya için bu yaklaşık 55 saat sürecek ...

Aşağıdaki komut dosyasını kullanarak silme oranı ~% 75 arttı. Dosya listeleri oluşturulur ve yürütülür eşzamanlı süreçleri disk işlemleri artan (ama doğrusal değil.) 4 çatal gösteriyorum, ancak iki yeterli olabilir.

Listeleri hazırlamak için gereken süreyi önemli ölçüde azaltan PowerShell kullanma seçeneği vardır.

BTW, çarpışmalara izin veren iki doğrudan del işlemi kullanarak test ettim, ancak tek bir del operasyonuna kıyasla toplam silme süresinde belirgin bir azalma yoktu. Ve silme listeleri oluşturmak istenmeyebilse de, kaydedilen zaman buna değdi.

@ECHO OFF
SETLOCAL EnableDelayedExpansion

IF /I "%~1"=="timestamp" (
    CALL :ECHOTIMESTAMP
    GOTO END
)

rem directory structure to delete
SET "DELETE=c:\_delete\Content.IE5\???<<<change this>>>???"
rem primary list of discovered files to delete
SET "LIST=delete-list.txt"
rem base path for sub-lists
SET "LISTBASE=.\delete-list"
SET "TITLE=Batch Delete Process"
rem specifies number of batch delete processes to spawn
SET FORKS=4
rem when set to 1, use PowerShell for list building and delete.  Definitely improves time to build fork sublists
SET POWERSHELL=0
rem specifies max files to delete when greater than 0
SET MAXDEL=1000000

rem prompt for confirmatoin
SET /P CONT=About to delete all files and directories from !DELETE!. Continue (Y/N)?
IF /I NOT "!CONT!"=="Y" EXIT /B

CALL :ECHOTIMESTAMP

ECHO Accumulating list of files to delete...
dir /b /s "!DELETE!" > "!LIST!"

FOR /F "delims=" %%c IN ('type "!LIST!" ^| find /C ":"') DO SET "COUNT=%%c"
ECHO Discoverd !COUNT! files and directories to delete.

IF  %MAXDEL% GTR 0 IF !COUNT! GTR %MAXDEL% (
    SET COUNT=%MAXDEL%
    ECHO Limiting files/directories deletion count to  !COUNT!
)

CALL :ECHOTIMESTAMP
ECHO Preparing !FORKS! delete processes...
SET /A LIMIT=!COUNT!/!FORKS!

IF !POWERSHELL! EQU 1 (
    SET SKIP=0
    FOR /L %%n IN (1,1,!FORKS!) DO (
        SET "CURRENT=!LISTBASE!-%%n.txt"
        SET "LIST[%%n]=!CURRENT!"
        DEL /f /q "!CURRENT!" > nul 2>&1
        IF %%n EQU !FORKS! SET /A LIMIT+=!FORKS!
        SET CMD=type \"!LIST!\" ^| select -first !LIMIT! -skip !SKIP!
        powershell -command "& {!CMD!}" > "!CURRENT!"
        SET /A SKIP+=!LIMIT!
    )

) ELSE (
    rem significantly slower but no PowerShell.
    SET L=1
    SET N=!LIMIT!
    SET C=0
    FOR /F %%f  IN (!LIST!) DO (
        IF !C! LSS !COUNT! (
            IF !N! GEQ !LIMIT! (
                SET "CURRENT=!LISTBASE!-!L!.txt"
                SET "LIST[!L!]=!CURRENT!"
                DEL /f /q "!CURRENT!" > nul 2>&1
                SET /A L+=1
                SET /A N=0
            ) ELSE (
                SET /A N+=1
            )
            ECHO %%f >> "!CURRENT!"
        ) ELSE (
            GOTO ENDLIST
        )
        SET /A C+=1
    )
)
:ENDLIST

CALL :ECHOTIMESTAMP
ECHO Forking !FORKS! delete processes...
FOR /L %%t IN (1,1,!FORKS!) DO (

    SET "CURRENT=!LIST[%%t]!"
    IF !POWERSHELL! EQU 1 (
        SET "TAB=        "
        SET BLANK=!TAB!!TAB!!TAB!!TAB!!TAB!!TAB!!TAB!!TAB!
        SET BLANK=!BLANK!!BLANK!!BLANK!!BLANK!
        SET DEL_CMD=del -force -recurse -ea SilentlyContinue -path \"$_\"
        SET $W_CMD=$w=$Host.UI.RawUI.WindowSize.Width
        SET $S_CMD=$s=\"$_\";$i=[math]::max^(0,$s.length-$w^);$s=$s.substring^($i, $s.length-$i^);$s=\"$s !BLANK!\";$s=$s.substring^(0,[math]::min($w,$s.length^)^)
        SET ECHO_CMD=Write-Host \"`r$s\" -NoNewLine
        SET CMD=type \"!CURRENT!\" ^| %% {!DEL_CMD!; !$W_CMD!; !$S_CMD!; !ECHO_CMD!}
        SET CMD=powershell -command "^& {!CMD!}" ^& ECHO\ ^& "%~dpnx0" timestamp
        ECHO CMD !CMD!
    ) ELSE (
        SET LOOP=FOR /F %%%f IN ^(!CURRENT!^) DO
        SET OP=del "%%%f"
        SET CMD=@ECHO OFF ^&^& ^(!LOOP! !OP!  ^> nul 2^>^&1 ^)  ^& "%~dpnx0" timestamp
    )
    rem ECHO !CMD!
    START "!TITLE! %%t" cmd /k  !CMD!
)

GOTO END

:ECHOTIMESTAMP
SETLOCAL
    SET DATESTAMP=!DATE:~10,4!-!DATE:~4,2!-!DATE:~7,2!
    SET TIMESTAMP=!TIME:~0,2!-!TIME:~3,2!-!TIME:~6,2!
    ECHO !DATESTAMP: =0!-!TIMESTAMP: =0!
ENDLOCAL
GOTO :EOF

:END
ENDLOCAL
EXIT /B

2

Bunu deneyin ve istediğiniz gibi değiştirin ..

Bu Win2003 üzerinde test komut Synetech en dayanmaktadır Teknik Açıklama ve Analiz 15:22 15 Ekim '13 cevap

@echo off

rem ### USE FULL PATH AS FIRST ARGUMENT TO SCRIPT, DONT FORGET QUOTES !
rem ### If you move this script, fix script path variable...
SET STATICFULLSCRIPTPATH="D:\scripts\FOLDER"
SET SCRIPTNAME="DeleteFast.bat"

rem ### If CD fails or IF condition has problems,
rem ### and DEL or RMDIR runs, its better to be at safe place.
if not exist "%TEMP%\SAFE" mkdir "%TEMP%\SAFE"
if exist "%TEMP%\SAFE" cd /d "%TEMP%\SAFE"

rem ### Fix quote overflow
set var1="%1"
set var1=%var1:"=%

if not [%1]==[] (
    cd /d "%var1%"

    echo # KILLING F AT : "%var1%"
    rem ### uncomment to do damage! ### 
    rem # del /f/q * > nul

    for /d %%i in (*) do call "%STATICFULLSCRIPTPATH%\%SCRIPTNAME%" "%var1%\%%i"

    rem ## Finish deleting the last dir
    cd /d "%var1%\.."

echo # KILLING  DIR : "%var1%"
rem ## Remove dir.. first try
rmdir /q "%var1%"

if exist "%var1%" (
    rem ## Remove dir.. second try
    rem ## If thousands of files/dirs had permission/ownership problems, then prepare to wait a long time.
    rem ### uncomment to do damage! ### 
    rem #cmd.exe /c takeown /f "%var1%" && icacls "%var1%" /grant SOMEBODY:F

    rem ### uncomment to do damage! ### 
    rem #rmdir /s/q "%var1%"
)
)

cd /d "%STATICFULLSCRIPTPATH%"

Testrun .. A1 - A4, B1 - B4 ve C1 - C4 gibi klasörler farklı şekilde yuvalanmıştır.

Z:\>"D:\scripts\FOLDER\DeleteFast.bat" "D:\scripts\TESTF\DIRS"
# KILLING F AT : "D:\scripts\TESTF\DIRS"
# KILLING F AT : "D:\scripts\TESTF\DIRS\A1"
# KILLING F AT : "D:\scripts\TESTF\DIRS\A1\B1"
# KILLING F AT : "D:\scripts\TESTF\DIRS\A1\B1\C 1"
# KILLING  DIR : "D:\scripts\TESTF\DIRS\A1\B1\C 1"
# KILLING  DIR : "D:\scripts\TESTF\DIRS\A1\B1"
# KILLING F AT : "D:\scripts\TESTF\DIRS\A1\B2"
# KILLING F AT : "D:\scripts\TESTF\DIRS\A1\B2\C 2"
# KILLING  DIR : "D:\scripts\TESTF\DIRS\A1\B2\C 2"
# KILLING  DIR : "D:\scripts\TESTF\DIRS\A1\B2"
# KILLING  DIR : "D:\scripts\TESTF\DIRS\A1"
# KILLING F AT : "D:\scripts\TESTF\DIRS\A2"
# KILLING F AT : "D:\scripts\TESTF\DIRS\A2\B3"
# KILLING F AT : "D:\scripts\TESTF\DIRS\A2\B3\C 3"
# KILLING  DIR : "D:\scripts\TESTF\DIRS\A2\B3\C 3"
# KILLING  DIR : "D:\scripts\TESTF\DIRS\A2\B3"
# KILLING  DIR : "D:\scripts\TESTF\DIRS\A2"
# KILLING F AT : "D:\scripts\TESTF\DIRS\A3"
# KILLING F AT : "D:\scripts\TESTF\DIRS\A3\B4"
# KILLING F AT : "D:\scripts\TESTF\DIRS\A3\B4\C 4"
# KILLING  DIR : "D:\scripts\TESTF\DIRS\A3\B4\C 4"
# KILLING  DIR : "D:\scripts\TESTF\DIRS\A3\B4"
# KILLING  DIR : "D:\scripts\TESTF\DIRS\A3"
# KILLING F AT : "D:\scripts\TESTF\DIRS\A4"
# KILLING  DIR : "D:\scripts\TESTF\DIRS\A4"
# KILLING  DIR : "D:\scripts\TESTF\DIRS"

D:\scripts\FOLDER>

Yorum yapamıyorum (site benim itibarımdan şikayet ediyor), bu yüzden buraya yorumumu ekliyorum ..

Bjv'nin çözümü usuless geçici filelistler oluşturur. Ve sonra gerçek işi yapmak için onları ikinci kez tekrarlar. /superuser//a/892412/528695

Orijinal Synetech'in senaryosu benim için çalışmadı. /superuser//a/416469/528695

@echo off
if not [%1]==[] cd /d %1
echo "%1"
for /d %%i in (*) do call %0 "%%i"

Sonuçlar..

Z:\>C:\privscripts\TESTF\DeleteFastORIGINAL.bat "C:\privscripts\TESTF\DIRS"
""C:\privscripts\TESTF\DIRS""
""A1""
""B1""
""C1""
The system cannot find the path specified.
""B2""
The system cannot find the path specified.
""A2""
The system cannot find the path specified.
""A3""
The system cannot find the path specified.
""A4""

C:\privscripts\TESTF\DIRS\A1\B1\C1>

Synetech'in komut dosyasının çalışmadığını söylediğinde @ user4350129'un doğru olduğunu doğrulayabilirim - Win7x64 kutumda da aynı davranış vardı.
leinad13

Lanet benim senaryo ya da mükemmel değildi, eğer arg eksik ve alıntı taşma takeown anc icacls komutları kırdı eğer sorunları .. Ayrıca ben sadece dosyaları değil klasörleri kontrol .. Bu sorunları düzeltti .. sonrası düzenlenmiş, ama her zaman kullanmadan önce test.
EO

2

Daha önce 10 milyon dosya ile benzer sorunlar yaşadım ama bir sunucu 2003'te dosyaları silmek için bir ftp sunucusu / istemci kullandım ve istemcinin dosyaları ve klasörleri silmesini bıraktım. Yavaş bir çözüm ama mükemmel çalışıyor.

Muhtemelen hiçbir çözümü olmayan NTFS MFT ile ikinci bir sorun olacak, MFT win 2003 (Microsoft 2003 2003 sonra bir çözüm var mı emin değilim) tüm dosyaları artımlı bir şekilde saklıyor bir dizi olduğunu bu yüzden trilyon dosya ile boyut çılgın olacak, benim durumumda MFT'nin 17 milyon kaydı vardı ve MFT'nin boyutu sadece 45000 dosya ile 19GB civarındaydı, diğer sistemlerde test ettim ve MFT'nin yapacağını 1 milyon kayıt gibi görünüyor 1 GB civarında olmalıdır.

MFT'nin durumunu şu komutla kontrol edebilirsiniz:

defrag C: /a /v
  • C: - birim mektup
  • /a - analiz et
  • /v - ayrıntılı

Başka bir zor çözüm, MFT'yi küçülten bir araç olmadığından, araçlar sadece dosya ve özelliklerin adını 0 ile doldurur, ancak daha fazlasını değil, ancak VMware dönüştürücüsünü veya başka bir P2V türünü kullanabilir ve Sunucunuz, bu şekilde MFT ile ilgili tüm sorunları çözeceksiniz, V2P'den dönüşümü hiç test etmedim, şimdi sadece sanal ortamlarda çalışıyorum, ancak internette birçok bilgi gördüm.

Bu 2003 kazanmak şimdi mükemmel çalışıyor, MFT boyutu 40MB ve her şey yolunda, isterseniz size yedeklemeler, dolandırıcılık veya milyonlarca küçük dosya ile ilgili diğer görevler hakkında daha fazla bilgi verebilirim.



1

Dosyaları bir kerede silmek çok fazla bellek kullandığından, dosyaları birer birer silmek için bir yol gerekir, ancak işlem otomatiktir. Unix tarzı bir kabukta bu tür şeyler yapmak çok daha kolay, bu yüzden Cygwin'i kullanalım. Aşağıdaki komut, sıradan dosyaların bir listesini oluşturur, bu listeyi bir rmkomut dizisine dönüştürür , sonra ortaya çıkan komut dosyasını bir kabuğa besler.

 find dir \! -type d | sed 's/^/rm /' | sh

Komut dosyası, oluşturuluyor olsa bile yürütülüyor ve döngüler yok, bu nedenle kabuğun (umarım) büyük geçici dosyalar oluşturması gerekmez. Komut dosyası milyonlarca satır uzunluğunda olduğundan, kesinlikle biraz zaman alacaktır. Çalıştırmak için rmkomutu ayarlamanız gerekebilir (belki de kullanmalıydım -f? Ama dosyalarınızı benden daha iyi anlıyorsunuz).

Artık dizinlerden başka bir şey kalmadı. İşte işlerin burada donduğu. Belki yeterli rm -rfbelleği sildiniz, böylece belleğiniz tükenmeden yapabilirsiniz (ve muhtemelen başka bir komut dosyasından daha hızlı olacaktır). Değilse, bu Stackoverflow yanıtını uyarlayabiliriz :

 find dir | perl -lne 'print tr:/::, " $_"' | sort -n | cut -d' ' -f2 | sed 's/^/rmdir /' | sh

Yine, sortbüyük geçici dosyalar oluşturmaktan kaçınmak için bu kez ince ayar yapmak gerekebilir .


1

Aynı konuya bir süre önce rastladım. Tam olarak bunu yapan küçük bir yardımcı program yazdım: özyineli olarak bir dizini silmek. Dosyaları numaralandırmaz ve n = maksimum dizin derinliği ve alt dizinlerden birinde m = maksimum dosya / dizin sayısı ile maksimum bellek (O (n + m) tüketmez). Uzun dosya yollarını (> 256 karakter) işleyebilir. Bu sorununuzu çözebilirseniz geri bildirim almak isterim.

Burada bulabilirsiniz: https://github.com/McNetic/fdeltree (sürümler klasöründe yürütülebilir)


1

Bu iş parçacığı, desteklediğim birkaç sunucuda 3 milyondan fazla dosyayı silmek için sahip olduğumdan daha iyi bir yol arıyor. Yukarıda karmaşık IMO üzerinden yol vardır, bu yüzden Windows "FORFILES" komut satırı aracını kullanarak bilinen yöntem kullanarak sona erdi (bu Server 2003 idi).

Her neyse, bir klasördeki TÜM dosyaları komut satırından silmek için kullandığım FORFILES komutu aşağıdadır.

forfiles / P "BURADA KLASÖR YOLUNUZ (örn. C: \ Windows \ Temp)" / C "cmd / c echo @file & del / f / q @file"

Yukarıda da ECHO ekrana silinmekte olan dosyaların adı, ama ben sadece bir şey ilerleme gerçekten görmek istedim çünkü bir şey yankılamazsanız, sadece DOS kutusu asılı gibi görünüyor, hatta iş beklendiği gibi Tamam olsa.

Başlaması biraz zaman alıyor, yani bir süre hiçbir şey yapmıyor gibi görünüyor (~ 3 milyon dosya için yaklaşık 30m), ancak sonunda dosya adlarının silindikçe görünmeye başladığını görmelisiniz. Bu yöntem ayrıca (silme süresi dosyaları silmek için uzun zaman alır olabilir yankı? Olmaksızın azaltılabilir), ancak silme işlemi sırasında belleğin ~ 1,850Kb kullanıyordu benim sunucu forfiles üzerinde, makineyi çökmesini olmadan sonunda çalışır .. .

Silme süresi, sunucularınızın fareyi hareket ettirmek için otomatik oturum kapatma özelliğine sahip olması durumunda bir soruna neden olabilir (Konsol kullanıcısı olarak çalışmanızı veya LanDesk veya SCCM vb. exe))

Her neyse, cevabımı paylaşacağımı düşündüm, iyi şanslar!

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.