Копировать папку на WinRT
Сейчас я просто знаю, как скопировать файл, используя:
IStorageFolder dir = Windows.Storage.ApplicationData.Current.LocalFolder;
IStorageFile file = await StorageFile.GetFileFromApplicationUriAsync(
new Uri("ms-appx:///file.txt"));
await file.CopyAsync(dir, "file.txt");
Когда я пытаюсь скопировать папку и весь контент внутри, я не могу найти API как CopyAsync
выше.
Можно ли скопировать папку и весь контент в WinRT?
4 ответа
Приведенный выше код меня не удовлетворял (слишком конкретный), я сделал свой собственный, так что решил, что могу поделиться им:
public static async Task CopyFolderAsync(StorageFolder source, StorageFolder destinationContainer, string desiredName = null)
{
StorageFolder destinationFolder = null;
destinationFolder = await destinationContainer.CreateFolderAsync(
desiredName ?? source.Name, CreationCollisionOption.ReplaceExisting);
foreach (var file in await source.GetFilesAsync())
{
await file.CopyAsync(destinationFolder, file.Name, NameCollisionOption.ReplaceExisting);
}
foreach (var folder in await source.GetFoldersAsync())
{
await CopyFolderAsync(folder, destinationFolder);
}
}
Одна из возможностей будет использовать
StorageFolder.GetItemsAsync();
от Windows.Storage
-namespace.
Результатом звонка является
IReadOnlyList<IStorageItem>
содержащий все файлы и папки текущей папки. Затем вы можете работать над этим.
См. MSDN для дальнейшей ссылки.
Не уверен, что C# поддерживает метод Array.map, но именно так будет выглядеть код copyFolderAsync для JavaScript
CreationCollisionOption = Windows.Storage.CreationCollisionOption;
NameCollisionOption = Windows.Storage.NameCollisionOption;
copyFolderAsync = function(sourceFolder, destFolder) {
return destFolder.createFolderAsync(sourceFolder.name, CreationCollisionOption.openIfExists).then(function(destSubFolder) {
return sourceFolder.getFilesAsync().then(function(files) {
return WinJS.Promise.join(files.map(function(file) {
return file.copyAsync(destSubFolder, file.name, NameCollisionOption.replaceExisting);
}));
}).then(function() {
return sourceFolder.getFoldersAsync();
}).then(function(folders) {
return WinJS.Promise.join(folders.map(function(folder) {
return copyFolderAsync(folder, destSubFolder);
}));
});
});
};
Основываясь на ответе bash.d, я создаю свою собственную папку для копирования:
namespace Directories
{
private string ROOT = "root";
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
CopyFolder(ROOT);
}
private async void CopyFolder(string path)
{
IStorageFolder destination = Windows.Storage.ApplicationData.Current.LocalFolder;
IStorageFolder root = Windows.ApplicationModel.Package.Current.InstalledLocation;
if (path.Equals(ROOT) && !await FolderExistAsync(ROOT))
await destination.CreateFolderAsync(ROOT);
destination = await destination.GetFolderAsync(path);
root = await root.GetFolderAsync(path);
IReadOnlyList<IStorageItem> items = await root.GetItemsAsync();
foreach (IStorageItem item in items)
{
if (item.GetType() == typeof(StorageFile))
{
IStorageFile presFile = await StorageFile.GetFileFromApplicationUriAsync(
new Uri("ms-appx:///" + path.Replace("\\", "/") + "/" + item.Name));
// Do copy file to destination folder
await presFile.CopyAsync(destination);
}
else
{
// If folder doesn't exist, than create new one on destination folder
if (!await FolderExistAsync(path + "\\" + item.Name))
await destination.CreateFolderAsync(item.Name);
// Do recursive copy for every items inside
CopyFolder(path + "\\" + item.Name);
}
}
}
private async Task<bool> FolderExistAsync(string foldername)
{
IStorageFolder destination = Windows.Storage.ApplicationData.Current.LocalFolder;
try
{
await destination.GetFolderAsync(foldername);
return true;
}
catch (Exception ex)
{
return false;
}
}
}
}
Этот пример с использованием root
в качестве корневой папки:
- root
- sub1
- sub1-1.txt
- sub1-2.txt
- sub1-3.txt
- sub1-4.txt
- sub2
- sub2-1.txt
- sub2-2.txt
- sub2-3.txt
- sub2-4.txt
- root1.txt
- root2.txt
- root3.txt
- root4.txt
Это будет копировать из InstalledLocation
папка для LocalFolder
,