1. Öffnungsanalyse
Der sogenannte Pufferpuffer bedeutet "temporärer Speicherbereich", ein Speicher, in dem die Daten- und Ausgabedaten vorübergehend gespeichert sind.
Die JS -Sprache selbst hat nur String -Datentypen und keine binären Datentypen. Daher bietet NodeJS einen globalen Konstruktorpuffer, der Peer to String ist, um Operationen für binäre Daten bereitzustellen. Zusätzlich zum Lesen von Dateien, um Pufferinstanzen zu erhalten, kann es auch direkt konstruiert werden, beispielsweise:
Die Codekopie lautet wie folgt:
var buffer = neuer buffer ([0x68, 0x65, 0x6c, 0x6c, 0x6f]);
Puffer ähnelt einer Zeichenfolge. Zusätzlich zur Verwendung des Attributs .Length, um die Bytelänge zu erhalten, können Sie auch die [Index] -Methode verwenden, um die Bytes an der angegebenen Position zu lesen, z. B.:
Die Codekopie lautet wie folgt:
Puffer [0]; // 0x68;
Puffer und String können ineinander konvertiert werden. Beispielsweise können binäre Daten unter Verwendung einer angegebenen Codierung in Zeichenfolgen konvertiert werden:
Die Codekopie lautet wie folgt:
var str = buffer.toString ("utf-8"); // Hallo
Konvertiert eine Zeichenfolge in binäre Daten unter der angegebenen Codierung:
Die Codekopie lautet wie folgt:
var buffer = new buffer ("hello", "utf-8"); // <Puffer 68 65 6c 6c 6f>
Ein kleiner Unterschied:
Es gibt einen wichtigen Unterschied zwischen einem Puffer und einer Zeichenfolge. Die Zeichenfolge ist nur schreibgeschützt, und jede Änderung der Zeichenfolge führt zu einer neuen Zeichenfolge, und die ursprüngliche Zeichenfolge bleibt unverändert.
Für Puffer ist es eher ein C-Spracharray, das Zeigervorgänge ausführen kann. Beispielsweise können die Bytes an einer bestimmten Position direkt in der [Index] -Methode geändert werden.
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Die Slice -Methode gibt keinen neuen Puffer zurück, sondern einen Zeiger an einen Ort in der Mitte des ursprünglichen Puffers, wie unten gezeigt.
[0x68, 0x65, 0x6c, 0x6c, 0x6f]
^ ^ ^
| |
bin bin.lice (2)
Daher wirkt die Änderung des von der Slice -Methode zurückgegebenen Puffer auf den ursprünglichen Puffer, beispielsweise auf den ursprünglichen Puffer:
Die Codekopie lautet wie folgt:
var buffer = neuer buffer ([0x68, 0x65, 0x6c, 0x6c, 0x6f]);
var sub = bin.lice (2);
sub [0] = 0x65;
console.log (puffer); // <Puffer 68 65 65 6c 6f>
Wenn Sie einen Puffer kopieren möchten, müssen Sie zuerst einen neuen Puffer erstellen und die Daten im Originalpuffer über die .Copy -Methode kopieren.
Dies ähnelt der Bewerbung für ein neues Speicherstück und das Kopieren der Daten im vorhandenen Speicher. Hier ist ein Beispiel.
Die Codekopie lautet wie folgt:
var buffer = neuer buffer ([0x68, 0x65, 0x6c, 0x6c, 0x6f]);
var dup = neuer Buffer (bin.length);
Puffer.Copy (DUP);
DUP [0] = 0x48;
console.log (puffer); // <Puffer 68 65 6c 6c 6f>
console.log (DUP); // <Puffer 48 65 65 6c 6f>
Kurz gesagt, Puffer erweitert die Datenverarbeitungsfunktionen von JS von Zeichenfolgen auf willkürliche Binärdaten.
Mit dem obigen können Sie kurz verstehen, was ein Puffer ist. Lassen Sie uns darüber sprechen, wie man es benutzt, und in den folgenden spezifischen Nutzungsszenarien.
Zweitens sprechen Sie über Puffer
JavaScript ist sehr freundlich zur String -Verarbeitung und ob es sich um eine breite Byte- oder Einzel -Byte -Zeichenfolge handelt, es wird als Zeichenfolge angesehen. Der Knoten muss Netzwerkprotokolle, Betriebsdatenbanken, Verarbeitung von Bildern, Uploads von Dateien usw. verarbeiten und auch eine große Anzahl von Binärdaten verarbeiten. Die mit ihnen verbundenen Saiten sind weit davon entfernt, diese Anforderungen zu erfüllen, so dass der Puffer entstanden ist.
Pufferstruktur
Puffer ist ein typisches Modul, das JavaScript und C ++ kombiniert. Der leistungsbezogene Teil wird in C ++ implementiert und der nicht-flacherbezogene Teil wird in JavaScript implementiert.
Der Knoten wird in den Speicher eingebaut, wenn der Vorgang startet und in das globale Objekt steckt, sodass dies nicht erforderlich ist.
Pufferobjekt: Ähnlich wie bei einem Array sind seine Elemente in Hexadezimal zweistellig.
Pufferspeicherzuweisung
Die Speicherzuweisung des Pufferobjekts befindet sich nicht im Heap -Speicher von V8, sondern implementiert die Speicheranwendung auf der C ++ - Node -Ebene.
Um die Speicheranwendung effizient zu verwenden, verwendet der Knoten den Slab -Allokationsmechanismus, der ein dynamischer Speicherverwaltungsmechanismus ist, der verschiedene *NIX -Betriebssysteme anwendet. Es gibt drei Plattenzustände:
(1) voll: vollständig zugewiesener Zustand
(2) teilweise: teilweise Zuordnungsstatus
(3) leer: kein zugewiesener Zustand
Pufferkonvertierung
Pufferobjekte können in Saiten umgewandelt werden, und die unterstützten Codierungstypen sind wie folgt:
ASCII, UTF-8, UTF-16LE/UCS-2, BASE64, BINARY, HEX
String zum Puffer
neuer Puffer (STR, [Codierung]), Standard UTF-8
buf.write (String, [Offset], [Länge], [Codierung])
Puffer zu String
buf.tostring ([codieren], [starten], [Ende])
Codierungstypen, die nicht vom Puffer unterstützt werden
Stellen Sie fest, ob es es durch Buffer.ISencoding (Codierung) unterstützt.
ICONV-LITE: Pure JavaScript-Implementierung, leichtere, bessere Leistung ohne C ++ für JavaScript-Konvertierung
ICONV: Die Libiconv -Bibliothek in C ++ rufen
Pufferspleißen
Hinweis "Res.on ('Data', Funktion (Chunk) {})", wobei der Parameter -Chunk ein Pufferobjekt ist. Die direkte Verwendung von + Stichen wird automatisch in eine Zeichenfolge konvertiert. Für breite Byte -Zeichen kann der verstümmelte Code stattfinden.
Lösung:
(1) Durch die Methode SetEnCoding () im lesbaren Stream kann das Datenereignis ein Pufferobjekt übergeben, jedoch eine codierte Zeichenfolge, und das Stringencoder -Modul wird intern verwendet.
(2) Speichern des Pufferobjekts in ein Array und schließlich zu einem großen Puffer zusammen, kodieren Sie es dann in eine Stringausgabe.
Puffer wird in der Datei -E/A- und Netzwerk -E/A häufig verwendet, und seine Leistung ist von großer Bedeutung und ist viel höher als die der gewöhnlichen Zeichenfolgen.
Zusätzlich zum Leistungsverlust der String -Konvertierung ist bei Verwendung eines Puffers eine Hochwassermark -Einstellung für die Leistungswirkung beim Lesen einer Datei von entscheidender Bedeutung.
A. Hochwassermark -Einstellungen haben einen gewissen Einfluss auf die Zuordnung und Verwendung des Pufferspeichers.
B. Die Highwatermark -Einstellung ist zu klein, was zu zu vielen Systemanrufen führen kann.
Wann sollte ich Puffer verwenden, wann sollte ich es nicht verwenden? Bei der Lösung von TCP -Streams oder Dateiströmen müssen Streams verarbeitet werden. Wenn wir Nicht-UTF-8-Saiten, binäre und andere Formate speichern, müssen wir "Puffer" verwenden.
3. Einführen Sie Beispiele
Die Codekopie lautet wie folgt:
var buf = neuer Buffer ("Dies ist Textconat -Test!"), Str = "Dies ist Textconat -Test!" ;
console.time ("Puffer concider test!");
var list = [];
var len = 100000 * buf.length;
für (var i = 0; i <100000; i ++) {
list.push (buf);
len += buf.length;
}
var s1 = buffer.concat (list, len) .toString ();
console.timeend ("Pufferconciat -Test!");
console.time ("String concat test!");
var list = [];
für (var i = 100000; i> = 0; i--) {
list.push (str);
}
var s2 = list.join ("");
console.timeend ("String concat test!");
Das Folgende sind die laufenden Ergebnisse:
Die Lesegeschwindigkeit ist definitiv schneller und der Puffer benötigt auch den Betrieb von toString (). Wenn wir also Saiten sparen, müssen wir noch String verwenden. Selbst wenn wir Strings in großen Saiten spleißen, ist die Geschwindigkeit der Saiten nicht langsamer als Puffer.
Wann müssen wir Puffer wieder verwenden? Wenn es keinen Weg gibt, müssen wir sie verwenden, wenn wir Nicht-UTF-8-Saiten, binäre und andere Formate speichern.
Vier, lasst uns zusammenfassen
(1) JavaScript eignet sich zur Verarbeitung von Unicode -codierten Daten, ist jedoch nicht zur Verarbeitung von Binärdaten freundlich.
(2), bei der Verarbeitung von TCP -Streams oder Dateisystemen müssen Oktettströme verarbeitet werden.
(3) hat der Knoten verschiedene Methoden zum Verarbeiten, Erstellen und Verbrauch von Oktettströmen.
(4) Die Rohdaten werden in einer Pufferinstanz gespeichert. Ein Puffer ähnelt einem Ganzzahl -Array, sein Speicher wird jedoch außerhalb des V8 -Stacks zugewiesen. Die Größe eines Puffers kann nicht geändert werden.
(5), die verarbeiteten Codierungstypen sind: ASCII, UTF8, UTF16LE, UCS2 (Alias für UTF16LE), Base64, Binary, Hex.
(6) Puffer ist ein globales Element, und eine Pufferinstanz wird von direkt neuem Puffer () erhalten.