A palavra "fluxo" foi escolhida porque representa (na vida real) um significado muito semelhante ao que queremos transmitir quando o usamos.
Vamos esquecer um pouco a loja de apoio e começar a pensar na analogia de um fluxo de água. Você recebe um fluxo contínuo de dados, assim como a água flui continuamente em um rio. Você não sabe necessariamente de onde vêm os dados e, na maioria das vezes, não precisa; seja de um arquivo, soquete ou qualquer outra fonte, não importa (não deveria) realmente. Isso é muito semelhante ao recebimento de um fluxo de água, pelo qual você não precisa saber de onde ele vem; seja de um lago, de uma fonte ou de qualquer outra fonte, não importa (não deveria) realmente.
Dito isto, uma vez que você começa a pensar que só se preocupa em obter os dados necessários, independentemente de onde eles vêm, as abstrações que as outras pessoas mencionaram se tornam mais claras. Você começa a pensar que pode agrupar fluxos e seus métodos ainda funcionarão perfeitamente. Por exemplo, você pode fazer isso:
int ReadInt(StreamReader reader) { return Int32.Parse(reader.ReadLine()); }
// in another method:
Stream fileStream = new FileStream("My Data.dat");
Stream zipStream = new ZipDecompressorStream(fileStream);
Stream decryptedStream = new DecryptionStream(zipStream);
StreamReader reader = new StreamReader(decryptedStream);
int x = ReadInt(reader);
Como você vê, fica muito fácil alterar sua fonte de entrada sem alterar sua lógica de processamento. Por exemplo, para ler seus dados de um soquete de rede em vez de um arquivo:
Stream stream = new NetworkStream(mySocket);
StreamReader reader = new StreamReader(stream);
int x = ReadInt(reader);
Tão fácil quanto possível. E a beleza continua, pois você pode usar qualquer tipo de fonte de entrada, desde que seja possível criar um "wrapper" de fluxo para ela. Você pode até fazer isso:
public class RandomNumbersStreamReader : StreamReader {
private Random random = new Random();
public String ReadLine() { return random.Next().ToString(); }
}
// and to call it:
int x = ReadInt(new RandomNumbersStreamReader());
Vejo? Desde que o seu método não se importe com a fonte de entrada, você pode personalizá-la de várias maneiras. A abstração permite dissociar a entrada da lógica de processamento de uma maneira muito elegante.
Observe que o fluxo que criamos a nós mesmos não tem uma loja de apoio, mas ainda serve perfeitamente a nossos propósitos.
Então, para resumir, um fluxo é apenas uma fonte de entrada, escondendo (abstraindo) outra fonte. Contanto que você não quebre a abstração, seu código será muito flexível.
ReadInt
é definido no topoint.Parse
, usando , que recebe a string retornadareader.ReadLine()
e a analisa. Claro que você pode criar umReadString
método semelhante . Isso é claro o suficiente?Stream.Copy
torna a vida muito mais fácil em muitos aplicativos.O ponto é que você não precisa saber qual é a loja de suporte - é uma abstração sobre ela. De fato, pode até não haver uma loja de apoio - você pode estar lendo a partir de uma rede e os dados nunca são "armazenados".
Se você pode escrever um código que funcione, esteja você falando com um sistema de arquivos, memória, rede ou qualquer outra coisa que suporte a ideia de fluxo, seu código é muito mais flexível.
Além disso, os fluxos geralmente são encadeados - você pode ter um fluxo que comprime o que quer que seja colocado nele, gravando o formulário compactado em outro fluxo ou criptografando os dados, etc. descriptografar, descomprimir ou qualquer outra coisa.
fonte
StreamReader
- ou melhor, aTextReader
, seu código não saberá que tipo de fluxo está subjacente ao fluxo de dados. Ou melhor, ele pode usar aBaseStream
propriedade para descobrir o tipo - mas pode ser um tipo que seu código nunca viu antes. O ponto é que você não deveria se importar. E sim, você pode absolutamente escrever código que às vezes será usado para um fluxo de rede e, às vezes, para um fluxo de arquivos. Quanto aos fluxos de dados de tubulação através de um processo - bem, isso não seria feito dentro do processo ... seria o provedor do fluxo.O objetivo do fluxo é fornecer uma camada de abstração entre você e o armazenamento de suporte. Portanto, um determinado bloco de código que usa um fluxo não precisa se importar se o armazenamento de backup é um arquivo de disco, memória, etc ...
fonte
Não é sobre riachos - é sobre nadar. Se você pode nadar em um stream, então você pode nadar em qualquer stream que encontrar.
fonte
Para adicionar à câmara de eco, o fluxo é uma abstração, para que você não se importe com o armazenamento subjacente. Faz mais sentido quando você considera cenários com e sem fluxos.
Os arquivos são desinteressantes, na maioria das vezes, porque os fluxos não fazem muito acima e além dos métodos não baseados em fluxo com os quais estou familiarizado. Vamos começar com arquivos da Internet.
Se eu quiser baixar um arquivo da Internet, tenho que abrir um soquete TCP, fazer uma conexão e receber bytes até que não haja mais bytes. Eu tenho que gerenciar um buffer, saber o tamanho do arquivo esperado e escrever código para detectar quando a conexão é interrompida e lidar com isso adequadamente.
Digamos que eu tenho algum tipo de objeto TcpDataStream. Eu o crio com as informações de conexão apropriadas e leio os bytes do fluxo até que ele diga que não há mais bytes. O fluxo lida com o gerenciamento de buffer, as condições de final de dados e o gerenciamento de conexões.
Dessa maneira, os fluxos facilitam a E / S. Você certamente poderia escrever uma classe TcpFileDownloader que faz o que o fluxo faz, mas então você tem uma classe específica para o TCP. A maioria das interfaces de fluxo simplesmente fornece um método Read () e Write (), e quaisquer conceitos mais complicados são tratados pela implementação interna. Por esse motivo, você pode usar o mesmo código básico para ler ou gravar na memória, arquivos de disco, soquetes e muitos outros armazenamentos de dados.
fonte
A visualização que uso são correias transportadoras, não em fábricas reais porque não sei nada sobre isso, mas em fábricas de cartum em que os itens se movem ao longo das linhas e são carimbados, encaixotados, contados e verificados por uma sequência de dispositivos burros.
Você tem componentes simples que fazem uma coisa, por exemplo, um dispositivo para colocar uma cereja em um bolo. Este dispositivo possui um fluxo de entrada de bolos sem cereja e um fluxo de saída de bolos com cerejas. Vale a pena mencionar três vantagens em estruturar seu processamento dessa maneira.
Em primeiro lugar, ele simplifica os componentes: se você deseja colocar cobertura de chocolate em um bolo, não precisa de um dispositivo complicado que saiba tudo sobre bolos, pode criar um dispositivo idiota que cola a cobertura de chocolate no que quer que seja alimentado ( os desenhos animados, isso chega ao ponto de não saber que o próximo item não é um bolo, é Wile E. Coyote).
Em segundo lugar, você pode criar produtos diferentes colocando os dispositivos em diferentes seqüências: talvez você queira que seus bolos tenham cobertura em cima da cereja em vez de cereja em cima da cobertura, e você pode fazer isso simplesmente trocando os dispositivos pela linha .
Em terceiro lugar, os dispositivos não precisam gerenciar inventário, boxe ou unboxing. A maneira mais eficiente de agregar e empacotar as coisas é mutável: talvez hoje você esteja colocando seus bolos em caixas de 48 e enviando-os pelo caminhão, mas amanhã você deseja enviar caixas de seis em resposta a pedidos personalizados. Esse tipo de alteração pode ser acomodado substituindo ou reconfigurando as máquinas no início e no final da linha de produção; a máquina cerejeira no meio da linha não precisa ser alterada para processar um número diferente de itens de cada vez, sempre trabalha com um item de cada vez e não precisa saber como é sua entrada ou saída. sendo agrupado.
fonte
Quando ouvi falar sobre streaming pela primeira vez, foi no contexto de transmissão ao vivo com uma webcam. Portanto, um host está transmitindo conteúdo de vídeo e o outro host está recebendo o conteúdo de vídeo. Então, isso está fluindo? Bem ... sim ... mas uma transmissão ao vivo é um conceito concreto, e acho que a pergunta se refere ao conceito abstrato de Streaming. Veja https://en.wikipedia.org/wiki/Live_streaming
Então vamos seguir em frente.
O vídeo não é o único recurso que pode ser transmitido. O áudio também pode ser transmitido. Então, agora estamos falando sobre streaming de mídia. Veja https://en.wikipedia.org/wiki/Streaming_media . O áudio pode ser entregue da fonte ao destino de várias maneiras. Então, vamos comparar alguns métodos de entrega de dados entre si.
Download de arquivo clássico O download de arquivo clássico não acontece em tempo real. Antes de usar o arquivo, você deverá aguardar a conclusão do download.
Download progressivo Os blocos de download progressivo baixam dados do arquivo de mídia transmitido para um buffer temporário. Os dados nesse buffer são viáveis: os dados de áudio e vídeo no buffer são reproduzíveis. Por esse motivo, os usuários podem assistir / ouvir o arquivo de mídia transmitido durante o download. É possível avançar e retroceder rapidamente, fora do curso dentro do buffer. De qualquer forma, o download progressivo não é uma transmissão ao vivo.
Streaming Acontece em tempo real e agrupa dados. O streaming é implementado em transmissões ao vivo. Os clientes que estão ouvindo a transmissão não podem avançar ou retroceder rapidamente. Nos fluxos de vídeo, os dados são descartados após a reprodução.
Um servidor de streaming mantém uma conexão bidirecional com seu cliente, enquanto um servidor da Web fecha a conexão após uma resposta do servidor.
Áudio e vídeo não são a única coisa que pode ser transmitida. Vamos dar uma olhada no conceito de fluxos no manual do PHP.
No PHP, um recurso é uma referência a uma fonte externa, como um arquivo, conexão com o banco de dados. Portanto, em outras palavras, um fluxo é uma fonte que pode ser lida ou gravada. Então, se você trabalhou com
fopen()
, então você já trabalhou com fluxos.Um exemplo de um arquivo de texto que está sujeito a streaming:
Arquivos zip também podem ser transmitidos. Além disso, o streaming não se limita a arquivos. As conexões HTTP, FTP, SSH e Entrada / Saída também podem ser transmitidas.
O que a wikipedia diz sobre o conceito de Streaming?
Veja: https://en.wikipedia.org/wiki/Stream_%28computing%29 .
Os links da Wikipedia para isso: https://srfi.schemers.org/srfi-41/srfi-41.html e os escritores têm isso a dizer sobre fluxos:
Portanto, um fluxo é realmente uma estrutura de dados.
Minha conclusão: um fluxo é uma fonte que pode conter dados que podem ser lidos ou gravados de maneira seqüencial. Um fluxo não lê tudo o que a fonte contém de uma só vez, lê / grava sequencialmente.
Links úteis:
fonte
É apenas um conceito, outro nível de abstração que facilita sua vida. E todos eles têm uma interface comum, o que significa que você pode combiná-los de maneira semelhante a um tubo. Por exemplo, codifique para base64, feche e grave-o no disco e tudo em uma linha!
fonte
A melhor explicação dos fluxos que eu vi é o capítulo 3 do SICP . (Você pode precisar ler os 2 primeiros capítulos para que faça sentido, mas você deve fazer assim mesmo. :-)
Eles não usam sterams para bytes, mas números inteiros. Os grandes pontos que obtive dele foram:
fonte
Outro ponto (para ler a situação do arquivo):
stream
pode permitir que você faça outra coisa antesfinished reading all content of the file
.fonte
Pense nos fluxos como uma fonte abstrata de dados (bytes, caracteres, etc.). Eles abstraem a mecânica real de leitura e gravação na fonte de dados concreta, seja um soquete de rede, arquivo em um disco ou uma resposta do servidor da web.
fonte
Eu acho que você precisa considerar que a própria loja de backup geralmente é apenas outra abstração. Um fluxo de memória é muito fácil de entender, mas um arquivo é radicalmente diferente dependendo do sistema de arquivos que você está usando, independentemente do disco rígido que está usando. Na verdade, nem todos os fluxos ficam no topo de uma loja de backup: os fluxos de rede praticamente são apenas fluxos.
O ponto de um fluxo é que restringimos nossa atenção ao que é importante. Por ter uma abstração padrão, podemos executar operações comuns. Mesmo que você não queira, por exemplo, pesquisar um arquivo ou uma resposta HTTP para URLs hoje, não significa que não desejará amanhã.
Os fluxos foram originalmente concebidos quando a memória era pequena se comparada ao armazenamento. Apenas ler um arquivo C pode ser uma carga significativa. Minimizar a pegada de memória foi extremamente importante. Portanto, uma abstração na qual muito pouco precisava ser carregado foi muito útil. Hoje, é igualmente útil ao executar comunicação em rede e, ao que parece, raramente é restritivo quando lidamos com arquivos. A capacidade de adicionar transparentemente itens como buffer de maneira geral o torna ainda mais útil.
fonte
Um fluxo é um resumo de uma sequência de bytes. A idéia é que você não precisa saber de onde vêm os bytes, apenas que você pode lê-los de maneira padronizada.
Por exemplo, se você processar dados por meio de um fluxo, não importará para o seu código se os dados vierem de um arquivo, uma conexão de rede, uma string, um blob em um banco de dados, etc, etc.
Não há nada de errado em interagir com a loja de backup em si, exceto pelo fato de vincular você à implementação da loja de backup.
fonte
Um fluxo é uma abstração que fornece um conjunto padrão de métodos e propriedades para interagir com dados. Ao abstrair da mídia de armazenamento real, seu código pode ser gravado sem total confiança no que é essa mídia ou mesmo na implementação dessa mídia.
Uma boa analogia pode ser considerar uma bolsa. Você não se importa com o que é feito ou o que uma bolsa faz quando coloca suas coisas nela, desde que a bolsa realize o trabalho de ser uma bolsa e você possa recuperá-las. Um fluxo define para a mídia de armazenamento o que o conceito de bolsa define para diferentes instâncias de uma bolsa (como bolsa de lixo, bolsa, mochila etc.) - as regras de interação.
fonte
Vou ser breve, eu estava perdendo a palavra aqui:
Os fluxos são filas geralmente armazenadas no buffer que contém qualquer tipo de dados.
(Agora, como todos sabemos o que são filas, não há necessidade de explicar isso mais.)
fonte