Je voudrais utiliser le WebClient
(ou il y a une autre meilleure option?) Mais il y a un problème. Je comprends que l'ouverture du flux prend du temps et cela ne peut être évité. Cependant, lire cela prend étrangement beaucoup plus de temps que de le lire entièrement immédiatement.Comment télécharger un fichier en chaîne avec rappel de progression?
Existe-t-il une meilleure façon de procéder? Je veux dire deux façons, de ficeler et de classer. Progress
est mon propre délégué et ça fonctionne bien.
Cinquième rapport:
Enfin, je réussi à le faire. En attendant j'ai vérifié quelques solutions qui m'ont fait réaliser que le problème est ailleurs.
J'ai testé des objets personnalisés WebResponse
et WebRequest
, la bibliothèque libCURL.NET
et même Sockets
.
La différence de temps était la compression gzip. La longueur du flux compressé était simplement la moitié de la longueur du flux normal et donc le temps de téléchargement était inférieur à 3 secondes avec le navigateur.
Je mets un peu de code si quelqu'un voudra savoir comment je résolu ce problème: (certains en-têtes ne sont pas nécessaires)
public static string DownloadString(string URL)
{
WebClient client = new WebClient();
client.Headers["User-Agent"] = "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/532.5 (KHTML, like Gecko) Chrome/4.1.249.1045 Safari/532.5";
client.Headers["Accept"] = "application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5";
client.Headers["Accept-Encoding"] = "gzip,deflate,sdch";
client.Headers["Accept-Charset"] = "ISO-8859-2,utf-8;q=0.7,*;q=0.3";
Stream inputStream = client.OpenRead(new Uri(URL));
MemoryStream memoryStream = new MemoryStream();
const int size = 32 * 4096;
byte[] buffer = new byte[size];
if (client.ResponseHeaders["Content-Encoding"] == "gzip")
{
inputStream = new GZipStream(inputStream, CompressionMode.Decompress);
}
int count = 0;
do
{
count = inputStream.Read(buffer, 0, size);
if (count > 0)
{
memoryStream.Write(buffer, 0, count);
}
}
while (count > 0);
string result = Encoding.Default.GetString(memoryStream.ToArray());
memoryStream.Close();
inputStream.Close();
return result;
}
Je pense que les fonctions asyncro seront presque les mêmes. Mais je vais simplement utiliser un autre thread pour déclencher cette fonction. Je n'ai pas besoin d'indication de progression.
Qu'est-ce qui n'est pas si bon? Où est la chaîne à laquelle vous écrivez? – Marcel
Ce n'est pas un bon résultat parce que seulement 2048 (iSize) caractères de la fin du fichier. Et c'est très lent à télécharger tout. – Kaminari
Vous semblez lire le même 'Stream 'à deux endroits; 'lecteur' et' streamRemote' ... Je suis confus ... Aussi; attention: lorsque vous manipulez des octets, vous ne lisez pas toujours les blocs ('iByteSize') qui sont des nombres entiers de caractères. Il n'est également pas très clair comment les mises à jour de l'interface utilisateur se produisent dans le rappel; si cela implique un thread-switch qui ajoutera des retards (tout comme le 'DoEvents 'maudit). –