I am trying to download mltiple files simultaneosly. But all files are downloading one by one, sequantilly. So, at first this file downloaded #"http://download.geofabrik.de/europe/cyprus-latest.osm.pbf", and then this file is started to dowload #"http://download.geofabrik.de/europe/finland-latest.osm.pbf",, and the next file to be downloaded is #"http://download.geofabrik.de/europe/great-britain-latest.osm.pbf" and so on.
But I would like to download simultaneously.
So I've the following code based on the code from this answer:
static void Main(string[] args)
{
Task.Run(async () =>
{
await DownloadFiles();
}).GetAwaiter().GetResult();
}
public static async Task DownloadFiles()
{
IList<string> urls = new List<string>
{
#"http://download.geofabrik.de/europe/cyprus-latest.osm.pbf",
#"http://download.geofabrik.de/europe/finland-latest.osm.pbf",
#"http://download.geofabrik.de/europe/great-britain-latest.osm.pbf",
#"http://download.geofabrik.de/europe/belgium-latest.osm.pbf",
#"http://download.geofabrik.de/europe/belgium-latest.osm.pbf"
};
foreach (var url in urls)
{
string fileName = url.Substring(url.LastIndexOf('/'));
await DownloadFile(url, fileName);
}
}
public static async Task DownloadFile(string url, string fileName)
{
string address = #"D:\Downloads";
using (var client = new WebClient())
{
await client.DownloadFileTaskAsync(url, $"{address}{fileName}");
}
}
However, when I see in my file system, then I see that files are downloading one by one, sequantially, not simultaneosuly:
In addition, I've tried to use this approach, however there are no simultaneous downloads:
static void Main(string[] args)
{
IList<string> urls = new List<string>
{
#"http://download.geofabrik.de/europe/cyprus-latest.osm.pbf",
#"http://download.geofabrik.de/europe/finland-latest.osm.pbf",
#"http://download.geofabrik.de/europe/great-britain-latest.osm.pbf",
#"http://download.geofabrik.de/europe/belgium-latest.osm.pbf",
#"http://download.geofabrik.de/europe/belgium-latest.osm.pbf"
};
Parallel.ForEach(urls,
new ParallelOptions { MaxDegreeOfParallelism = 10 },
DownloadFile);
}
public static void DownloadFile(string url)
{
string address = #"D:\Downloads";
using (var sr = new StreamReader(WebRequest.Create(url)
.GetResponse().GetResponseStream()))
using (var sw = new StreamWriter(address + url.Substring(url.LastIndexOf('/'))))
{
sw.Write(sr.ReadToEnd());
}
}
Could you tell me how it is possible to download simultaneosly?
Any help would be greatly appreciated.
foreach (var url in urls)
{
string fileName = url.Substring(url.LastIndexOf('/'));
await DownloadFile(url, fileName); // you wait to download the item and then move the next
}
Instead you should create tasks and wait all of them to complete.
public static Task DownloadFiles()
{
IList<string> urls = new List<string>
{
#"http://download.geofabrik.de/europe/cyprus-latest.osm.pbf",
#"http://download.geofabrik.de/europe/finland-latest.osm.pbf",
#"http://download.geofabrik.de/europe/great-britain-latest.osm.pbf",
#"http://download.geofabrik.de/europe/belgium-latest.osm.pbf",
#"http://download.geofabrik.de/europe/belgium-latest.osm.pbf"
};
var tasks = urls.Select(url=> {
var fileName = url.Substring(url.LastIndexOf('/'));
return DownloadFile(url, fileName);
}).ToArray();
return Task.WhenAll(tasks);
}
Rest of your code can remain same.
Eldar's solution works with some minor edits. This is the full working DownloadFiles method that was edited:
public static async Task DownloadFiles()
{
IList<string> urls = new List<string>
{
#"http://download.geofabrik.de/europe/cyprus-latest.osm.pbf",
#"http://download.geofabrik.de/europe/finland-latest.osm.pbf",
#"http://download.geofabrik.de/europe/great-britain-latest.osm.pbf",
#"http://download.geofabrik.de/europe/belgium-latest.osm.pbf",
#"http://download.geofabrik.de/europe/belgium-latest.osm.pbf"
};
var tasks = urls.Select(t => {
var fileName = t.Substring(t.LastIndexOf('/'));
return DownloadFile(t, fileName);
}).ToArray();
await Task.WhenAll(tasks);
}
this will download them asynchronously one after each other.
await DownloadFile(url, fileName);
await DownloadFile(url2, fileName2);
this will do what you actually want to achieve:
var task1 = DownloadFile(url, fileName);
var task2 = DownloadFile(url2, fileName2);
await Task.WhenAll(task1, task2);
I am developing a Windows 10 UWP application and anytime I run the below code, I get the following execption:
'UnauthorizedAccessException - Access to path {path name} is denied'.
I have tried the several windows folders (path) :
Pictures,
Videos
Desktop etc.
This is my code:
public async Task GetFiles() // edit added wrapper method for readability
{
var filePicker = new FileOpenPicker();
filePicker.FileTypeFilter.Add("*");
Windows.Storage.StorageFile file = await filePicker.PickSingleFileAsync();
if (file != null)
{
ChosenFiles.ItemsSource = GetFileInfo(file.Path);
}
}
public List<string> GetFileInfo(string path)
{
List<string> files = new List<string>();
string[] allFiles = Directory.GetFiles(path);
foreach (var file in allFiles)
{
FileInfo Info = new FileInfo(file);
files.Add(Info.Name);
}
return files;
}
System.IO.Directory seems to only have direct access to app package and app local storage folders. That means you should rather use StorageFile and StorageFolder classes to extract information you need. For example:
private async void ButtonBase_OnClick(object sender, RoutedEventArgs args)
{
var folderPicker = new FolderPicker();
var folder = await folderPicker.PickSingleFolderAsync();
if (folder != null)
{
ChosenFiles.ItemsSource = await GetFileInfoAsync(folder);
}
}
public async Task<List<string>> GetFileInfoAsync(StorageFolder folder)
{
List<string> files = new List<string>();
var allFiles = await folder.GetFilesAsync();
foreach (var file in allFiles)
{
files.Add(file.Name);
}
return files;
}
Note that if you picked a file, you can't enumerate its neighbors because you don't have access to its parent folder. So for your scenario you should use FolderPicker.
I want to read all images files from some folder in the local hard drive (including sub folders) with a UWP app.
im starting with FolderPicker so the user can pick the wanted folder:
public async static Task<string> GetFolderPathFromTheUser()
{
FolderPicker folderPicker = new FolderPicker();
folderPicker.ViewMode = PickerViewMode.Thumbnail;
folderPicker.FileTypeFilter.Add(".");
var folder = await folderPicker.PickSingleFolderAsync();
return folder.Path;
}
after successfully getting the folder path i'm trying to access the folder:
public async static Task<bool> IsContainImageFiles(string path)
{
StorageFolder folder = await StorageFolder.GetFolderFromPathAsync(path);
IReadOnlyList<StorageFile> temp= await folder.GetFilesAsync();
foreach (StorageFile sf in temp)
{
if (sf.ContentType == "jpg")
return true;
}
return false;
}
and then I'm getting the next exception :
An exception of type 'System.UnauthorizedAccessException' occurred in mscorlib.ni.dll but was not handled in user code
WinRT information: Cannot access the specified file or folder (D:\test). The item is not in a location that the application has access to (including application data folders, folders that are accessible via capabilities, and persisted items in the StorageApplicationPermissions lists). Verify that the file is not marked with system or hidden file attributes.
So how can I get access to read the files from the folder?
Thanks.
Once you get a folder from the file picker, you may not be able to access the folder through its path. You need to directly use the StorageFolder instance returned:
public async static Task<IStorageFolder> GetFolderPathFromTheUser()
{
FolderPicker folderPicker = new FolderPicker();
folderPicker.ViewMode = PickerViewMode.Thumbnail;
folderPicker.FileTypeFilter.Add(".");
var folder = await folderPicker.PickSingleFolderAsync();
return folder;
}
public async static Task<bool> IsContainImageFiles(IStorageFolder folder)
{
IReadOnlyList<StorageFile> temp= await folder.GetFilesAsync();
foreach (StorageFile sf in temp)
{
if (sf.ContentType == "jpg")
return true;
}
return false;
}
If you want to access it later, you should add it to future access list and keep the returned token:
public async static Task<string> GetFolderPathFromTheUser()
{
FolderPicker folderPicker = new FolderPicker();
folderPicker.ViewMode = PickerViewMode.Thumbnail;
folderPicker.FileTypeFilter.Add(".");
var folder = await folderPicker.PickSingleFolderAsync();
return FutureAccessList.Add(folder);
}
public async static Task<bool> IsContainImageFiles(string accessToken)
{
IStorageFolder folder = await FutureAccessList.GetFolderAsync(accessToken);
IReadOnlyList<StorageFile> temp= await folder.GetFilesAsync();
foreach (StorageFile sf in temp)
{
if (sf.ContentType == "jpg")
return true;
}
return false;
}
I use Live SDK 5.6 and I'm trying to download file from OneDrive. Using CreateBackgroundDownloadAsync (innerItem.ID + "/Content"), why is result file null?
foreach (var innerItem in resultItems.data)
{
if (innerItem.name == "MoneyNote.db")
{
LiveDownloadOperation operation = await liveConnectClient.CreateBackgroundDownloadAsync(innerItem.id + "/Content");
//LiveDownloadOperationResult downloadResult = await operation.StartAsync();
var downloadResult = await operation.StartAsync();
if (downloadResult.File != null)
{
StorageFile downFile = await ApplicationData.Current.LocalFolder.GetFileAsync("MoneyNote.db");
await downloadResult.File.MoveAndReplaceAsync(downFile);
messagePrint(true);
}
else
{
messagePrint(false);
}
}
}
I think the problem may be, because you are creating background download (not downloading in the background), then you start this download operation, but file needs time to be downloaded. In this case probably easier would be just to download a file like this:
foreach (var innerItem in resultItems.data)
{
if (innerItem.name == "MoneyNote.db")
{
StorageFile downFile = await ApplicationData.Current.LocalFolder.CreateFileAsync("MoneyNote.db", CreationCollisionOption.ReplaceExisting);
var result = await liveConnectClient.BackgroundDownloadAsync(innerItem.id + "/content", downFile);
messagePrint(true);
}
}
i have this c# code and i want to delete a certain sub directory in Documents Library. However this produces an error because the directory is not empty. I hope someone can guide me on how to do this.
thank you for any prompt reply.
StorageFolder storageFolder = KnownFolders.DocumentsLibrary;
var queryResult = storageFolder.CreateFolderQuery();
IReadOnlyList<StorageFolder> folderList = await queryResult.GetFoldersAsync();
foreach (StorageFolder folder in folderList)
{
await folder.DeleteAsync();
}
You could use the StorageFolder.GetFilesAsync() to obtain a list of all the files present in the folders and delete them prior to deleting the folders since there is no way in the DeleteAsync() method to specify subfolders and files.
More info: StorageFolder class | MSDN
Hope this may help.
public async void deletefile()
{
StorageFolder sourceFolder = ApplicationData.Current.TemporaryFolder;
// sourceFolder = await sourceFolder.GetFolderAsync("Test");
// await sourceFolder.DeleteAsync(StorageDeleteOption.PermanentDelete);
// var files = await sourceFolder.GetFilesAsync();
IReadOnlyList<StorageFile> folderList = await sourceFolder.GetFilesAsync();
if (folderList.Count > 0)
{
foreach (StorageFile f1 in folderList)
{
await f1.DeleteAsync(StorageDeleteOption.PermanentDelete);
}
}
//StorageFile retfile = await ApplicationData.Current.TemporaryFolder.GetFileAsync("MysoundFile.mp3");
// if (retfile != null)
// {
// await retfile.DeleteAsync(StorageDeleteOption.PermanentDelete);
// }
}