Tôi có một thư mục:
c: \ test
Tôi đang thử mã này:
File.Move(@"c:\test\SomeFile.txt", @"c:\test\Test");
Tôi nhận được ngoại lệ:
Tập tin đã tồn tại
Thư mục đầu ra chắc chắn tồn tại và tệp đầu vào ở đó.
Tôi có một thư mục:
c: \ test
Tôi đang thử mã này:
File.Move(@"c:\test\SomeFile.txt", @"c:\test\Test");
Tôi nhận được ngoại lệ:
Tập tin đã tồn tại
Thư mục đầu ra chắc chắn tồn tại và tệp đầu vào ở đó.
Câu trả lời:
Bạn cần phải di chuyển nó sang một tệp khác (thay vì một thư mục), điều này cũng có thể được sử dụng để đổi tên.
Di chuyển:
File.Move(@"c:\test\SomeFile.txt", @"c:\test\Test\SomeFile.txt");
Đổi tên:
File.Move(@"c:\test\SomeFile.txt", @"c:\test\SomeFile2.txt");
Lý do nó cho biết "Tệp đã tồn tại" trong ví dụ của bạn, là vì C:\test\Test
cố gắng tạo tệp Test
không có phần mở rộng, nhưng không thể làm như vậy vì đã tồn tại một thư mục có cùng tên.
Những gì bạn cần là:
if (!File.Exists(@"c:\test\Test\SomeFile.txt")) {
File.Move(@"c:\test\SomeFile.txt", @"c:\test\Test\SomeFile.txt");
}
hoặc là
if (File.Exists(@"c:\test\Test\SomeFile.txt")) {
File.Delete(@"c:\test\Test\SomeFile.txt");
}
File.Move(@"c:\test\SomeFile.txt", @"c:\test\Test\SomeFile.txt");
Điều này sẽ:
Chỉnh sửa: Tôi nên làm rõ câu trả lời của mình, mặc dù đó là câu trả lời được ủng hộ nhiều nhất! Tham số thứ hai của File.Move phải là tệp đích - không phải là một thư mục. Bạn đang chỉ định tham số thứ hai là thư mục đích, không phải tên tệp đích - đó là những gì File.Move yêu cầu. Vì vậy, tham số thứ hai của bạn nên là c:\test\Test\SomeFile.txt
.
Cá nhân tôi thích phương pháp này hơn. Thao tác này sẽ ghi đè lên tệp trên đích, xóa tệp nguồn và cũng ngăn việc xóa tệp nguồn khi sao chép không thành công.
string source = @"c:\test\SomeFile.txt";
string destination = @"c:\test\test\SomeFile.txt";
try
{
File.Copy(source, destination, true);
File.Delete(source);
}
catch
{
//some error handling
}
File.Copy , File.Delete
hơn File.Move
?
Bạn có thể thực hiện P / Gọi đến MoveFileEx()
- vượt qua 11 cho flags
( MOVEFILE_COPY_ALLOWED | MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH
)
[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("kernel32.dll", SetLastError=true, CharSet=CharSet.Unicode)]
static extern bool MoveFileEx(string existingFileName, string newFileName, int flags);
Hoặc, bạn có thể chỉ cần gọi
Microsoft.VisualBasic.FileIO.FileSystem.MoveFile(existingFileName, newFileName, true);
sau khi thêm Microsoft.VisualBasic làm tham chiếu.
Nếu tệp thực sự tồn tại và bạn muốn thay thế tệp, hãy sử dụng mã dưới đây:
string file = "c:\test\SomeFile.txt"
string moveTo = "c:\test\test\SomeFile.txt"
if (File.Exists(moveTo))
{
File.Delete(moveTo);
}
File.Move(file, moveTo);
Theo tài liệu cho File.Move không có tham số "ghi đè nếu tồn tại". Bạn đã cố gắng chỉ định thư mục đích , nhưng bạn phải cung cấp thông số kỹ thuật tệp đầy đủ.
Đọc lại tài liệu ("cung cấp tùy chọn để chỉ định tên tệp mới"), tôi nghĩ rằng việc thêm dấu gạch chéo ngược vào thông số thư mục đích có thể hoạt động.
Move(String, String, Boolean)
thay thế. nhưng đó có vẻ là một sai lầm?
1) Với C # trên .Net Core 3.0 trở lên, bây giờ có một tham số boolean thứ ba:
xem https://docs.microsoft.com/en-us/dotnet/api/system.io.file.move?view=netcore-3.1
In .NET Core 3.0 and later versions, you can call Move(String, String, Boolean) setting the parameter overwrite to true, which will replace the file if it exists.
2) Đối với tất cả các phiên bản khác của .Net, https://stackoverflow.com/a/42224803/887092 là câu trả lời tốt nhất. Sao chép bằng Ghi đè, sau đó xóa tệp nguồn. Điều này tốt hơn vì nó biến nó thành một hoạt động nguyên tử. (Tôi đã cố gắng cập nhật MS Docs bằng cái này)
Cố gắng Microsoft.VisualBasic.FileIO.FileSystem.MoveFile(Source, Destination, True)
. Tham số cuối cùng là Overwrite switch, System.IO.File.Move
không có.
Nếu bạn không có tùy chọn xóa tệp đã tồn tại ở vị trí mới, nhưng vẫn cần di chuyển và xóa khỏi vị trí ban đầu, thủ thuật đổi tên này có thể hoạt động:
string newFileLocation = @"c:\test\Test\SomeFile.txt";
while (File.Exists(newFileLocation)) {
newFileLocation = newFileLocation.Split('.')[0] + "_copy." + newFileLocation.Split('.')[1];
}
File.Move(@"c:\test\SomeFile.txt", newFileLocation);
Điều này giả định là duy nhất '.' trong tên tệp nằm trước phần mở rộng. Nó chia tệp tin ra làm hai trước phần mở rộng, đính kèm "_copy". ở giữa. Điều này cho phép bạn di chuyển tệp, nhưng tạo bản sao nếu tệp đã tồn tại hoặc bản sao của bản sao đã tồn tại hoặc bản sao của bản sao tồn tại ...;)