Enqueueing in NSInputStream?

8

Ich würde gerne drei "Teile" zu einem NSInputStream hinzufügen: einen NSString, eine Ausgabe von einem anderen Stream und dann einen weiteren NSString. Die Idee ist folgende:

Der erste und der letzte NSStrings stellen den Anfang und das Ende einer SOAP-Anfrage dar, während die Ausgabe aus dem Stream das Ergebnis des Ladens einer sehr großen Datei und deren Codierung als Base64-String ist. Also, am Ende hätte ich den letzten NSInputStream, der die gesamte SOAP-Anfrage so hält:

& lt; Seifenanfang & gt; & lt; Base64 codierte Daten & gt; & lt; Seifenend & gt;

Der Grund, warum die gesamte Anfrage in NSInputStream gehalten werden soll, ist zweifach:

  1. Ich was nicht, um die sehr große Datendatei in den Speicher
  2. zu laden
  3. Ich denke, dass dies die einzige Möglichkeit ist, das Senden der letzten Anfrage in HTTP 1.1-Chunks zu erzwingen (was ich benötige, weil der Server dies sonst nicht akzeptiert, wenn die Anfrage zu groß wird). Also, das weiß ich:

    %Vor%

stellt sicher, dass die Anfrage als HTTP 1.1-Chunks und nicht als eine riesige rohe SOAP-Anfrage gesendet wird.

Ich frage mich also, wie das erreicht werden kann - nämlich, wie kann ich Dinge in einen NSInputStream "einreihen"? Kann es überhaupt gemacht werden? Gibt es einen alternativen Weg?

Nur zur Referenz, in Java kann dies wie folgt gemacht werden

%Vor%

weil Java diese Objekte verfügbar hat, aber NStreams in objective-c wie Objekte sehr niedriger Ebene aussehen und mit denen sehr schwer zu arbeiten ist.

Hinweis: Ich habe die ursprüngliche Frage komplett neu geschrieben, wie ich es vor zwei Tagen gefragt habe, da ich denke, dass der neue Text deutlicher erklärt, was das Problem ist. Ich hoffe, es würde helfen, dass es leichter verstanden und vielleicht beantwortet wird.

UPDATE 2

Hier ist das, was ich bisher erreichen konnte: Anstatt zu versuchen, in einen Stream einzuordnen, verwende ich eine temporäre Datei, um zuerst das & lt; Soap-Anfang & gt ;, dann richte ich einen Eingabestrom ein, um aus der Datei in Chunks zu lesen, jeden Chunk als Base64-String zu codieren und diesen in die gleiche temporäre Datei zu schreiben. Schließlich, wenn mein Stream schließt, schreibe ich den & lt; Seifenend & gt; in die temporäre Datei. Dann richte ich einen weiteren Eingabestream mit dem Inhalt dieser Datei ein, den ich an NSMutableURLRequest weitergebe:

%Vor%

Dies stellt eine chunked HTTP 1.1 Übertragung der Inhalte der Datei sicher. Wenn die Verbindung beendet ist, löschen Sie die temporäre Datei.

Das scheint gut zu funktionieren, aber das ist natürlich eine lästige Arbeit. Ich möchte nicht in eine temporäre Datei schreiben, wenn alles durch Streams verarbeitet werden könnte (idealerweise.) Wenn jemand noch bessere Vorschläge hat, lass es mich wissen:)

UPDATE 3

OK, ein anderes Update ist in Ordnung. Während mein Schreiben in die Datei zu funktionieren scheint, stößt ich jetzt auf ein unerwartetes Problem, da einige meiner Anfragen nicht auf den Server hochgeladen werden konnten. Insbesondere läuft alles nach Plan, ich lese den Inhalt der Temp-Datei in einen Stream und setze den HTTP-Body meiner Anfrage als diesen Stream und es beginnt mit der Übertragung der HTTP 1.1-Chunks, so wie ich es möchte - aber für einige Grund dafür ist, dass einige Pakete gelöscht werden und die letzte Anfrage - das ist meine Vermutung - wird missgebildet und scheitert daher. Ich denke, das Problem der verlorenen Pakete ist zufällig, weil ich es bei größeren Anfragen beobachte - das heißt, das Problem hat einfach mehr Chancen, aufzutauchen, während meine kleineren Anfragen normalerweise gut gehen. Dies ist natürlich ein anderes Problem als das Original in dieser Frage. Wenn jemand eine gute Idee hat, was das verursachen könnte, fragte ich nach dem Problem hier: Pakete, die während der von NSURLConnection gesendeten Chunked HTTP 1.1-Anforderung gelöscht wurden

    
PeterD 05.03.2013, 23:28
quelle

1 Antwort

0

Ihre Lösung ist eine gute Option, aber Sie können es mit einem Stream tun. Das bedeutet, dass Sie NSInputStream ableiten müssen, und das ist nicht trivial, weil es eine Reihe von Methoden gibt, die Sie implementieren müssen.

Grundsätzlich würde Ihre Unterklasse zunächst die Header-Bytes zurückgeben, dann würde sie Bytes aus dem "internen" Stream zum Dateiinhalt zurückgeben, und wenn dies aufgebraucht ist, gibt sie die Fußzeilenbytes zurück. Es bedeutet, eine Aufzeichnung darüber zu führen, wie groß die Kopf- und Fußzeile ist und wie viel bisher verarbeitet wurde, aber das ist kein großes Problem.

Es gibt ein Beispiel für das Erstellen einer Unterklasse hier , die die trickreichen versteckten Methoden anzeigt, die Sie verwenden müssen implementiert werden, damit die Stream-Unterklasse ordnungsgemäß funktioniert, ohne Ausnahmen auszulösen.

    
Wain 05.07.2016 21:26
quelle

Tags und Links