2016-11-22 3 views
0

j'ai donc un code que je l'ai utilisé pour télécharger des fichiers dans mon application, le long des lignes de ce:Upload gros fichier via URLSession

var mutableURLRequest = URLRequest(url: url) 
var uploadData = try! Data(contentsOf: dataUrl) 
session.uploadTask(with: mutableURLRequest, from: uploadData).resume() 

Il y a un peu plus que cela, mais ceux-ci sont les parties pertinentes. Cependant, j'ai remarqué que pour certains grands fichiers vidéo Data(contentsOf: dataUrl) échoue depuis le fichier est trop gros pour charger dans la mémoire. Je veux restructurer ceci afin que je puisse streamer morceau par morceau sur le serveur sans avoir à charger le fichier entier en mémoire. Je l'ai déjà compris sur mon serveur, le seul morceau que je n'ai pas compris est comment obtenir un chunkSize morceau à partir des données dans une URL, sans le mettre dans un objet de données. Je veux essentiellement cette construction:

let chunkSize = 1024 * 1024 
let offset = 0 
let chunk = //get data from dataUrl of size chunkSize offset by offset 

//Upload each chunk and increment offset 

NSInputStream semblait prometteur de pouvoir le faire, mais je ne suis pas en mesure de comprendre le minimum mis en place afin de tirer octets d'un fichier sur le disque de cette façon. Quel code puis-je utiliser ci-dessus pour remplir la ligne let chunk = pour effectuer une telle tâche?

+0

Avez-vous essayé 'uploadTask (avec: fromFile:)'? Il pourrait être assez intelligent pour diffuser à partir du fichier plutôt que de charger le tout dans 'Data'. Ou peut-être utiliser 'uploadTask (withStreamedRequest:)'. – rmaddy

+0

Je suppose que ça ne va pas fonctionner pour moi puisque j'ai besoin de décorer chaque morceau avec une autre indésirable HTTP afin que mon serveur sache ce qui se passe. Cependant, tout ce qu'il utilise sous les couvertures pour faire cela peut être ce dont j'ai besoin. –

Répondre

0

J'ai une solution de travail, peut-être besoin d'un peu de peaufinage, mais semble fonctionner pour les gros fichiers que j'ai essayé:

public func getNextChunk() -> Data?{ 
    if _inputStream == nil { 
     _inputStream = InputStream(url: _url) 
     _inputStream?.open() 
    } 
    var buffer = [UInt8](repeating: 0, count: CHUNK_SIZE) 
    var len = _inputStream?.read(&buffer, maxLength: CHUNK_SIZE) 
    if len == 0 { 
     return nil 
    } 
    return Data(buffer) 
} 

Je demande aussi _inputStream?.close() sur deinit de ma classe qui gère le Chunking d'un fichier sur le disque.