2017-01-30 22 views
0

Я боролся с API Dropbox, и я сделал свои маленькие шаги (я новичок на C#). Дело в том, что я наконец достиг файла в моей учетной записи Dropbox, но я не знаю, как его создать на моей локальной машине через StreamWriter.Как написать файл Dropbox (через их API) с помощью StreamWriter в C#?

Примечание: Я знаю AWAIT вещь и так далее можно легко улучшить, но я все еще получаю в него: 'D

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using Dropbox.Api; 

namespace Try1Dropbox 
{ 
    class Program 
    { 
     private const string ApiKey = "$$longChickenToken%%!!xD"; 

     static void Main(string[] args) 
     { 
      try 
      { 
       var task = Task.Run(async() => await Program.Run()); 
       task.Wait(); 
      } 
      catch (AggregateException ex) 
      { 
       var inner = ex.InnerException; 
       Console.WriteLine(inner.Message); 
       Console.ReadKey(); 
      } 
     } 

     static async Task Run() 
     { 
      using (var dbx = new DropboxClient(ApiKey)) 
      { 
       var full = await dbx.Users.GetCurrentAccountAsync(); 
       await ListRootFolder(dbx); 
       Console.WriteLine("{0} - {1}", full.Name.DisplayName, full.Email); 
       Console.ReadKey(); 
       await Download(dbx, @"/", "remotefile.pdf"); 
      } 
     } 

     private static async Task ListRootFolder(DropboxClient dbx) 
     { 
      var list = await dbx.Files.ListFolderAsync(string.Empty); 

      // Show folders, then files 
      foreach (var item in list.Entries.Where(i => i.IsFolder)) 
      { 
       Console.WriteLine("D {0}/", item.Name); 
      } 
      foreach (var item in list.Entries.Where(i => i.IsFile)) 
      { 
       Console.WriteLine("F{0,8} {1}", item.AsFile.Size, item.Name); 
      } 
     } 

     private static async Task Download(DropboxClient dbx, string folder, string file) 
     { 
      string path = System.IO.Path.Combine(folder, file); 
      var args = new Dropbox.Api.Files.DownloadArg(path); 
      using (var response = await dbx.Files.DownloadAsync(args)) 
      { 
       using (var sw = new System.IO.StreamWriter(@"c:\prueba\localtest.pdf")) 
       { 
        Console.WriteLine(await response.GetContentAsStringAsync()); 
        sw.Write(response.GetContentAsByteArrayAsync()); 

        Console.ReadKey(); 
       } 
      } 
     } 
    } 
} 

Дело идет к sw.Write, где я «пытаются вставьте «ответ, который я получаю на консоли, но я просто получил это« System.Threading.Tasks.Task`1 [System.Byte []] »вместо этого.

Спасибо заранее и извините за n00bance. Новые в C# и Dropbox API.

+0

WriteLine печатает строковое представление возвращаемого объекта задачи. Разделите этот вызов на 'var response = await response ...', а затем распечатайте любое свойство, которое вы хотите напечатать. – Fildor

ответ

2

Вы написали следующее:

sw.Write(response.GetContentAsByteArrayAsync()); 

Во всяком случае, подпись метода

Task<byte[]> GetContentAsByteArrayAsync() 

Следовательно, вы передаёте Task<byte[]> - sw.Write(...). Поведение по умолчанию StreamWriter.Write - для переданного объекта - это write the text representation of an object - это имя типа для многих классов - это то, что вы видели. Кроме того, вы забыли await операцию async, поэтому у вас есть Task<byte[]>. Вы должны будете позвонить await, чтобы получить фактический byte[], а не Task<byte[]>. См. Звонок GetContentAsStringAsync.

Так как вы хотели бы, чтобы написать массив byte с здесь, вам не нужен StreamWriter, но могут работать на сырого (ну не точно, но более сырой, чем StreamWriter) потоки.

using (var stream = File.OpenWrite(@"c:\prueba\localtest.pdf")) 
{ 
    Console.WriteLine(await response.GetContentAsStringAsync()); 

    var dataToWrite = await response.GetContentAsByteArrayAsync(); 
    stream.Write(dataToWrite, 0, dataToWrite.Length); 

    Console.ReadKey(); 
} 
0

Глядя на документы API Dropbox, метод GetContentAsStringAsync(), являющийся async, возвращает Task<string>. Console.Writeline просто вызовет Task<string>.ToString(), и то, что вы видите, является реализацией по умолчанию метода ToString(). То, что вы хотите, чтобы написать фактический результат:

var taskResult = await response.GetContentAsStringAsync(); 

Console.WriteLine(taskResult.Result); 

Вы можете найти более подробную информацию о MSDN

0

ОК, наконец, я нашел решение!

private static async Task Download(DropboxClient dbx, string folder, string file) 
{ 
    string path = Path.Combine(folder, file); 
    var args = new Dropbox.Api.Files.DownloadArg(path); 
    using (var response = await dbx.Files.DownloadAsync(args)) 
    { 
     using (var sw = new StreamWriter(@"c:\prueba\localfile.pdf")) 
     { 
      Console.WriteLine(await response.GetContentAsStringAsync()); 
      var bytes = await response.GetContentAsByteArrayAsync(); 
      await sw.BaseStream.WriteAsync(bytes, 0, bytes.Length); 
      Console.ReadKey(); 
     } 
    } 
} 

Хорошо, магия ToString была не совсем такой магией XD Спасибо, ребята!

+1

См. Мой ответ: вы забыли «ожидание» и передали «Задача » на 'sw.Write (...)'. «ToString» вовсе не странный. –

+0

это не странно. 'Console.Writeline' будет просто вызывать' (Task ) .ToString() 'и то, что вы видите, является реализацией метода ToString()' по умолчанию. – peval27

+0

@PaulKertscher Спасибо всем! Полезно также! Я чувствую, что мне нужен швейцарский армейский нож и просто «зная», как использовать большой ключ ... – Gonzo345

Смежные вопросы