Move-Item causes "File Already Exists" error, despite folder having been deleted

  • 26,000
  • Tác giả: admin
  • Ngày đăng:
  • Lượt xem: 26
  • Tình trạng: Còn hàng

I have some code which deletes a thư mục, then copies files from a temporary directory đồ sộ where that thư mục had been.

Remove-Item -Path '.\index.html' -Force
Remove-Item -Path '.\generated' -Force -Recurse  #folder containing generated files

#Start-Sleep -Seconds 10 #uncommenting this line fixes the issue

#$tempDir contains index.html and a sub thư mục, "generated", which contains additional files.  
#i.e. we're replacing the nội dung we just deleted with new versions.
Get-ChildItem -Path $tempDir | %{
    Move-Item -Path $_.FullName -Destination $RelativePath -Force 
}

I get an intermittent error, Move-Item : Cannot create a tệp tin when that tệp tin already exists. on the Move-Item line for the generated path.

I've been able đồ sộ prevent this by adding a hacky Start-Sleep -Seconds 10 after the second Remove-Item statement; though that's not a great solution.

I assume the issue is that the Remove-Item statement completes / code moves on đồ sộ the next line, before the OS has caught up with the actual tệp tin deletion; though that seems odd/worrying. NB: There are ~2,500 files in the generated thư mục (all between 1-100 KBs).

There are no other processes accessing the folders (i.e. I've even closed my explorer windows và tested with this directory being excluded from my AV).

I've considered other options:

  • using Copy-Item instead of Move-Item. I don't lượt thích this as it requires creating new files when they're not required (i.e. a copy is slower than thở a move)... It's faster than thở my current sleep hack; but still not ideal.

  • deleting the files và not the thư mục, then iterating through the subfolders và copying files đồ sộ the new locations. This would work, but is a lot more code for something that should be simple; sánh I don't want đồ sộ pursue that option.

  • Robocopy would vì thế the trick; but I'd prefer a pure PowerShell solution. This is the option I'll eventually pick if there is no clean solution though.

Question

  • Has anyone seen this before?
  • Is it a bug, or have I missed something?
  • Is anyone aware of a fix / good workaround?

Update

Running the remove in a separate job (i.e. using the code below) did not resolve the issue.

Start-Job -ScriptBlock {
    Remove-Item -Path '.\index.html' -Force
    Remove-Item -Path '.\generated' -Force -Recurse  #folder containing generated files
} | Wait-Job | Out-Null

#$tempDir contains index.html and a sub thư mục, "generated", which contains additional files.  
#i.e. we're replacing the nội dung we just deleted with new versions.
Get-ChildItem -Path $tempDir | %{
    Move-Item -Path $_.FullName -Destination $RelativePath -Force 
}

Update #2

Adding this works; i.e. rather than thở waiting a fixed time, we wait for the path đồ sộ be removed / checking every second. If it's not removed after 30 seconds we assume it's not going đồ sộ be; sánh carry on regardless (which will cause the move-item đồ sộ throw an error which gets handled elsewhere).

# ... remove-item code ...
Start-Job -ScriptBlock {
    param($Path)
    while(Test-Path $Path){start-sleep -Seconds 1}
} -ArgumentList '.\generated' | Wait-Job -Timeout 30 | Out-Null
# ... move-item code ...