Pulling folder content
What can we do for you?
this is my code to pull the dcim image on the android main storage:
async Task DownloadFiles()
{
SyncService service = new SyncService(device);
string folderPath = Environment.CurrentDirectory + "/downloaded_files";
// Ensure the target folder exists, create it if needed
if (!Directory.Exists(folderPath))
{
Directory.CreateDirectory(folderPath);
}
string source = "/sdcard/dcim";
var files = await service.GetDirectoryListingAsync(source);
// Download each file and save it to the local folder
foreach (var file in files)
{
service = new SyncService(device);
string localFilePath = Path.Combine(folderPath, file.Path);
using (FileStream stream = File.OpenWrite(localFilePath))
{
string path = source + "/" + file.Path;
await service.PullAsync(path, stream);
}
}
}
I'm getting this error:
Failed to pull '/sdcard/dcim/Camera'. read failed: Is a directory
I can't specify in advance the full path, "/sdcard/dcim/camera" because my program need to pull the entire "dcim" content,and it might be dynamic content,and contain many other folders inside....is there any way to pull is like using the simple shell command "adb pull /sdcard/dcim"(which would do the work perfectly)?
Thanks in advance guys!
It takes my afternoon...
await PullFolderAsync("/sdcard/Documents/SAI", "C:/Users/qq251/Downloads/Compressed/Test");
async Task PullFolderAsync(string remotePath, string localPath)
{
if (!Directory.Exists(localPath))
{
Directory.CreateDirectory(localPath);
}
using SyncService service = new(device);
FileStatistics stat = await service.StatAsync(remotePath);
await PullFolderAsyncInternal(stat, remotePath, localPath);
async Task PullFolderAsyncInternal(FileStatistics stat, string remotePath, string localPath)
{
if (stat.FileType.HasFlag(UnixFileType.Directory))
{
if (remotePath != stat.Path)
{
localPath = Path.Combine(localPath, stat.Path);
remotePath = LinuxPath.Combine(remotePath, stat.Path);
}
if (!Directory.Exists(localPath))
{
Directory.CreateDirectory(localPath);
}
foreach (FileStatistics item in await service.GetDirectoryListingAsync(remotePath))
{
await PullFolderAsyncInternal(item, remotePath, localPath);
}
}
else if (stat.FileType.HasFlag(UnixFileType.Regular))
{
string localFilePath = Path.Combine(localPath, stat.Path);
await using FileStream stream = File.OpenWrite(localFilePath);
await service.PullAsync(LinuxPath.Combine(remotePath, stat.Path), stream);
await stream.FlushAsync();
}
}
}
@wherewhere Thank you so much sir!
But using your code leads to the famous The server returned an invalid sync response 0. error.
I'm using the lastest release,v3.1.10(wpf app)
Because I fixed it in new commit. You need to reopen the service after pull, push and list.
It will be like in next version
using SyncService service = new(device); await PullFolderAsync("/sdcard/Documents/SAI", "C:/Users/qq251/Downloads/Compressed/Test");
async Task PullFolderAsync(string remotePath, string localPath)
{
if (!Directory.Exists(localPath))
{
Directory.CreateDirectory(localPath);
}
using SyncService service = new(device);
FileStatistics stat = await service.StatAsync(remotePath);
await PullFolderAsyncInternal(stat, remotePath, localPath);
async Task PullFolderAsyncInternal(FileStatistics stat, string remotePath, string localPath)
{
switch (stat.FileMode.GetFileType())
{
case UnixFileStatus.Directory:
if (remotePath != stat.Path)
{
localPath = Path.Combine(localPath, stat.Path);
remotePath = LinuxPath.Combine(remotePath, stat.Path);
}
if (!Directory.Exists(localPath))
{
Directory.CreateDirectory(localPath);
}
foreach (FileStatistics item in await service.GetDirectoryListingAsync(remotePath))
{
await PullFolderAsyncInternal(item, remotePath, localPath);
}
break;
case UnixFileStatus.Regular:
string localFilePath = Path.Combine(localPath, stat.Path);
await using (FileStream stream = File.OpenWrite(localFilePath))
{
await service.PullAsync(LinuxPath.Combine(remotePath, stat.Path), stream);
await stream.FlushAsync();
}
break;
}
}
}
https://gist.github.com/wherewhere/53c49073c5da2c17536f99410899359d