Ønsker du en bedre forståelse af Buffer i Node.js? Se lige det her.

Er du altid mystificeret ligesom mig, når du støder på ord som Buffer, Stream og binære data iNode.js? Får den følelse dig til at krympe fra at forstå dem og tro, at de ikke er beregnet til dig, men kun for Node.js-guruer og pakkeudviklere at forstå?

Faktisk kan disse ord være meget skræmmende, især når du kommer ind i webudvikling med Node.js uden nogen CS-grader.

Desværre vil mange selvstudier og bøger springe direkte hen til undervisning i, hvordan man udvikler webapplikationer med Node.js-pakker uden at lade dig forstå kernefunktionerne i Node.js, og hvorfor de findes. Og nogle vil frimodigt fortælle dig, at du ikke behøver at forstå dem, fordi dumåske aldrig arbejde direkte med dem.

Nå, sandt, du arbejder muligvis aldrig direkte med dem, hvis du vælger at forblive en gennemsnitlig Node.js-udvikler.

Men hvis mysterier gør dig virkelig nysgerrig, og du stopper ved intet for at tilfredsstille din nysgerrighed, og hvis du vil tage din Node.js-forståelse til det næste niveau, så vil du virkelig grave dybere for at forstå de mange kerneegenskaber af Node.js, som f.eks. Buffer . Og det er netop derfor, jeg skriver dette stykke - for at hjælpe os med at afmystificere nogle af disse funktioner og tage vores Node.js-læring til det næste niveau.

Ved introduktion af buffer angiver de officielle Node.js-dokumenter delvis ...

... mekanisme til læsning eller manipulation af strømme af binære data. Den Bufferklassen blev indført som en del af node.js API til at gøre det muligt at interagere med Oktet vandløb i forbindelse med ting som TCP vandløb og filsystemoperationer.

Hmmm, medmindre du havde forudgående kendskab til alle ordene i ovenstående sætninger, er de sandsynligvis bare en masse jargon. Lad os prøve at forenkle det lidt ved at omformulere det, så vi kan have et klart fokus og ikke blive distraheret af de mange klokker og fløjter derinde. Uddrag fra denne introduktion kunne vi trygt sige:

Den Bufferklassen blev indført som en del af node.js API til at gøre det muligt at manipulere eller interagere med strømme af binære data.

Nu er det enklere, ikke? Men ... Buffer, streams, binære data ... stadig mange store ord. Lad os prøve at tackle disse store ord fra det sidste til det første.

Binære data, hvad er det?

Du ved sandsynligvis allerede, at computere gemmer og repræsenterer data i binære filer. Binær er simpelthen et sæt eller en samling på 1'ere og 0'ere. For eksempel er følgende fem forskellige binære filer, fem forskellige sæt med 1'er og 0'er:

10, 01, 001, 1110,00101011

Hvert nummer i en binær, hvert 1og 0i et sæt kaldes en bit , som er en kort form for binær cifre.

For at gemme eller repræsentere et stykke data skal en computer konvertere disse data til sin binære repræsentation. For eksempel for at gemme tallet 12 skal en computer konvertere 12 til sin binære repræsentation, hvilket er 1100.

Hvordan ved en computer, hvordan man foretager denne konvertering? Nå, det er ren matematik. Det er det enkle binære talsystem, vi lærte i grundlæggende matematik - at udtrykke et tal i base-2-talsystemet. Computere forstår den matematik.

Men tal er ikke den eneste datatype, vi arbejder med. Vi har også strenge, billeder og endda videoer. Computere ved, hvordan de skal repræsentere alle typer data i binære filer. Lad os f.eks. Tage strenge. Hvordan repræsenterer en computer strengen “L” i binære filer? For at gemme et hvilket som helst tegn i binære filer, vil computere først konvertere dette tegn til et tal og derefter konvertere dette nummer til dets binære repræsentation. Så for strengen "L",computere vil først konvertere L til et tal, der repræsenterer L . Lad os se hvordan.

Åbn din browser konsol og indsæt følgende kodestykke og derefter tryk enter: "L".charCodeAt(0). Hvad så du? Tallet 76? Det er det tal repræsentation eller Character Code eller Kode punkt af den karakter L . Men hvordan ved en computer, hvilket nøjagtigt antal der repræsenterer hvert tegn? Hvordan ved det at bruge tallet 76 til at repræsentere L ?

Tegnsæt

Tegnsæt er allerede definerede regler for, hvilket nøjagtigt antal der repræsenterer hvert tegn. Vi har forskellige definitioner af disse regler. De meget populære inkluderer Unicode og ASCII . JavaScript spiller rigtig godt med Unicode-tegnsæt. Faktisk er det den Unicode i din browser, der hedder, at 76 skal repræsentere L .

Så vi har set, hvordan computere repræsenterer tegn i tal. Nu vil computeren igen repræsentere tallet 76 til dets binære repræsentation. Du kan måske tænke, ja, bare konvertere 76 til base-2-talsystemet. Ikke så hurtigt!

Tegnkodning

Ligesom der er regler, der definerer, hvilket nummer der skal repræsentere et tegn, er der også regler, der definerer, hvordan dette nummer skal repræsenteres i binære filer. Specifikt hvor mange bits der skal bruges til at repræsentere nummeret. Dette kaldes tegnkodning .

En af definitionerne for tegnkodning er UTF-8 . UTF-8 angiver, at tegn skal kodes i bytes. En byte er et sæt på otte bits - otte 1'er og 0'er. Så otte 1'er og 0'er skal bruges til at repræsentere kodepunktet for ethvert tegn i binær.

For at forstå dette, som vi nævnte tidligere, er den binære repræsentation af tallet 12 1100. Så når UTF-8 siger, at 12 skal være i otte bits, siger UTF-8, at en computer skal tilføje flere bits til venstre for den faktiske base-2-repræsentation af tallet 12 for at gøre det til en byte. Så 12 skal opbevares som 00001100. Giver mening?

Derfor skal 76 opbevares som 01001100.

Dette, mine venner, er, hvordan computere gemmer strenge eller tegn i binære filer. På samme måde har computere også specificeret regler for, hvordan billeder og videoer skal konverteres eller kodes og lagres i binære filer. Pointen her er, at computere gemmer alle datatyper i binære filer, og dette kaldes binære data.

Hvis du er super interesseret i det nitty-gritty af Character Encoding, kan du måske lide denne blide og detaljerede introduktion.

Nu forstår vi hvad binære data er, men hvad er strømme af binære datafra vores introduktion til buffer?

Strøm

Stream i Node.js betyder simpelthen en sekvens af data, der flyttes fra det ene punkt til det andet over tid. Hele konceptet er, at du har en enorm mængde data at behandle, men du behøver ikke at vente på, at alle data er tilgængelige, før du begynder at behandle dem.

Dybest set er disse store data opdelt og sendt i bidder. Så fra den oprindelige definition af en buffer (“streams of binary data… in the context of… file system”) betyder det simpelthen, at binære data flyttes i filsystemet. For eksempel at flytte de tekster, der er gemt i file1.txt til file2.txt.

Men hvordan hjælper buffer os med at interagere med eller manipulere binære data under streaming? Hvad er denne buffer btw nøjagtigt?

Buffer

Vi har set, at en datastrøm er bevægelsen af ​​data fra det ene punkt til det andet, men hvordan flyttes de nøjagtigt ?

Typisk er dataflytning normalt med den hensigt at behandle det eller læse det og træffe beslutninger baseret på det. Men der er et minimum og en maksimal mængde data, som en proces kan tage over tid. Så hvis den hastighed, dataene ankommer, er hurtigere end den hastighed, som processen bruger dataene, skal de overskydende data vente et sted, indtil det bliver deres tur.

På den anden side, hvis processen bruger data hurtigere, end den ankommer, skal de få data, der ankommer tidligere, vente på, at en bestemt mængde data ankommer, før de sendes ud til behandling.

At "venteområde " er bufferen! Det er en lille fysisk placering på din computer, normalt i RAM, hvor data samles midlertidigt, venter og til sidst sendes til behandling under streaming.

Vi kan tænke på hele stream- og bufferprocessen som en busstation. På nogle busstationer har en bus ikke lov til at afgang, før en bestemt mængde passagerer ankommer, eller indtil en bestemt afgangstid. Passagererne kan også ankomme til forskellige tidspunkter med forskellig hastighed. Hverken passagererne eller busstationen har kontrol over passagerernes ankomst til stationen.

Under alle omstændigheder skal passagerer, der ankommer tidligere, vente, indtil busstationen beslutter at sende bussen på vej. Mens passagerer, der ankommer, når bussen allerede er i lastning, eller når bussen allerede er kørt, skal de vente på den næste bus.

Under alle omstændigheder er der altid et ventested. Det er Buffer to Node.js! Node.js kan ikke styre hastigheden eller tidspunktet for datainkomst, strømens hastighed. Det kan kun beslutte, hvornår det er tid til at sende dataene ud. Hvis det ikke er tid endnu, vil Node.js placere dem i bufferen - "venteområdet" - en lille placering i RAM'en, indtil det er tid til at sende dem ud til behandling.

Et typisk eksempel, hvor du kunne se buffer i aktion, er når du streamer en video online. Hvis din internetforbindelse er hurtig nok, vil strømens hastighed være hurtig nok til straks at fylde bufferen op og sende den til behandling, derefter udfylde en anden og sende den ud, så en anden og endnu en ... indtil strømmen er færdig.

Men hvis din forbindelse er langsom, efter at have behandlet det første sæt data, der ankom, vil videoafspilleren vise et indlæsningsikon eller vise teksten "buffering", hvilket betyder at indsamle flere data eller vente på, at flere data ankommer. Og når bufferen er fyldt op og behandlet, viser afspilleren dataene, videoen. Mens du spiller det, fortsætter flere data med at ankomme og vente i bufferen.

Hvis afspilleren er færdig med at behandle eller afspille de tidligere data, og bufferen endnu ikke er udfyldt, vises teksten "buffering" igen og venter på at indsamle flere data, der skal behandles.

Det er buffer!

Fra den oprindelige definition af en buffer viser det, at mens vi er i bufferen, kan vi manipulere eller interagere med de binære data, der streames. Hvilken interaktion kan vi muligvis have med disse rå binære data? Bufferimplementeringen i Node.js giver os en hel liste over, hvad der er muligt. Lad os se nogle af dem.

Interagerer med en buffer

Det er endda muligt at oprette din egen buffer! Bortset fra den ene vil Node.js automatisk oprette under en stream, er det muligt at oprette og manipulere din egen buffer. Interessant, ikke? Lad os oprette en!

Afhængigt af hvad du vil opnå, er der forskellige måder at oprette en buffer på. Lad os se nogle.

// Create an empty buffer of size 10. // A buffer that only can accommodate 10 bytes.
const buf1 = Buffer.alloc(10);
// Create a buffer with content
const buf2 = Buffer.from("hello buffer");

Når din buffer er oprettet, kan du begynde at interagere med den

// Examine the structure of a buffer
buf1.toJSON()// { type: 'Buffer', data: [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] }// an empty buffer
buf2.toJSON()// { type: 'Buffer', data: [ 104, 101, 108, 108, 111, 32, 98, 117, 102, 102, 101, 114 ] }
// the toJSON() method presents the data as the Unicode Code Points of the characters
// Examine the size of a buffer
buf1.length // 10
buf2.length // 12. Auto-assigned based on the initial content when created.
// Write to a bufferbuf1.write("Buffer really rocks!") 
// Decode a buffer
buf1.toString() // 'Buffer rea'
//oops, because buf1 is created to contain only 10 bytes, it couldn't accommodate the rest of the characters
// Compare two buffers

Der er en hel masse interaktioner, vi kunne have med en buffer. Gå videre til de officielle dokumenter for at spille mere med disse metoder.

Endelig efterlader jeg dig med denne lille udfordring: Gå og læs kilden til zlib.js , et af kernebibliotekerne i Node.js, for at se, hvordan det udnytter bufferen til at manipulere strømme af binære data. Disse viser sig at være gzipede filer. Når du læser, skal du dokumentere det, du lærer, og dele med os her i kommentarerne.

Jeg håber, at denne introduktion hjalp dig med at få en bedre forståelse af Node.js Buffer.

Hvis du har lyst til, at jeg har gjort et godt stykke arbejde, og at andre fortjener en chance for at se dette, bedes du klappe for artiklen for at hjælpe med at sprede en bedre forståelse af Buffer i vores Node.js-samfund.

Hvis du har et spørgsmål, der ikke er blevet besvaret, eller hvis du har en anden forståelse af nogle af punkterne her, er du velkommen til at droppe kommentarer her eller via Twitter.