Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pulling folder content #98

Open
itapi opened this issue Mar 11, 2024 · 5 comments
Open

Pulling folder content #98

itapi opened this issue Mar 11, 2024 · 5 comments
Labels
help wanted Extra attention is needed

Comments

@itapi
Copy link

itapi commented Mar 11, 2024

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!

@itapi itapi added the help wanted Extra attention is needed label Mar 11, 2024
@wherewhere
Copy link
Member

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();
        }
    }
}

@itapi
Copy link
Author

itapi commented Mar 12, 2024

@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)

@wherewhere
Copy link
Member

Because I fixed it in new commit.
You need to reopen the service after pull, push and list.

@wherewhere
Copy link
Member

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;
        }
    }
}

@wherewhere
Copy link
Member

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

2 participants