Tivemos uma discussão aqui no trabalho sobre por que fread e fwrite assumem um tamanho por membro e contam e retornam o número de membros lidos / escritos em vez de apenas pegar um buffer e tamanho. O único uso que podemos sugerir é se você quiser ler / gravar um conjunto de estruturas que não são divisíveis uniformemente pelo alinhamento da plataforma e, portanto, foram preenchidas, mas que não podem ser tão comuns a ponto de justificar essa escolha no design.
De FREAD (3) :
A função fread () lê nmemb elementos de dados, cada um com tamanho em bytes, do fluxo apontado por stream, armazenando-os no local fornecido por ptr.
A função fwrite () grava nmemb elementos de dados, cada tamanho bytes de comprimento, para o fluxo apontado por stream, obtendo-os da localização fornecida por ptr.
fread () e fwrite () retornam o número de itens lidos ou gravados com sucesso (ou seja, não o número de caracteres). Se ocorrer um erro ou se o fim do arquivo for atingido, o valor de retorno será uma contagem curta de itens (ou zero).
Respostas:
É baseado em como o fread é implementado.
A Especificação Única do UNIX diz
fgetc também tem esta nota:
Claro, isso é anterior a codificações sofisticadas de caracteres de bytes variáveis como UTF-8.
O SUS observa que isso é, na verdade, retirado dos documentos ISO C.
fonte
A diferença em fread (buf, 1000, 1, stream) e fread (buf, 1, 1000, stream) é que, no primeiro caso, você obtém apenas um pedaço de 1000 bytes ou nuthin, se o arquivo for menor e no segundo caso, você obtém tudo no arquivo com menos de e até 1000 bytes.
fonte
Isso é pura especulação, entretanto, no passado (alguns ainda estão por aí), muitos sistemas de arquivos não eram simples fluxos de bytes em um disco rígido.
Muitos sistemas de arquivos eram baseados em registros, portanto, para satisfazer tais sistemas de arquivos de maneira eficiente, você terá que especificar o número de itens ("registros"), permitindo que fwrite / fread opere no armazenamento como registros, não apenas fluxos de bytes.
fonte
Aqui, deixe-me corrigir essas funções:
Quanto a uma justificativa para os parâmetros para
fread()
/fwrite()
, perdi minha cópia de K&R há muito tempo, então só posso adivinhar. Acho que uma resposta provável é que Kernighan e Ritchie podem ter simplesmente pensado que a execução de E / S binárias seria feita de maneira mais natural em matrizes de objetos. Além disso, eles podem ter pensado que o bloco de E / S seria mais rápido / fácil de implementar ou qualquer outra coisa em algumas arquiteturas.Mesmo que o padrão C especifique que
fread()
efwrite()
seja implementado em termos defgetc()
efputc()
, lembre-se de que o padrão passou a existir muito depois de C ser definido por K&R e que as coisas especificadas no padrão podem não estar nas idéias originais dos designers. É até possível que as coisas ditas em "The C Programming Language" da K&R não sejam as mesmas de quando a linguagem estava sendo projetada pela primeira vez.Finalmente, aqui está o que PJ Plauger tem a dizer sobre
fread()
em "The Standard C Library":Basicamente, ele está dizendo que
fread()
a interface está quebrada. Poisfwrite()
ele observa que, "Erros de escrita são geralmente raros, então esta não é uma grande lacuna" - uma afirmação com a qual eu não concordaria.fonte
fread(buf, size*n, 1, stream);
se leituras incompletas são uma condição de erro, é mais simples organizar parafread
simplesmente retornar 0 ou 1 em vez do número de bytes lidos. Em seguida, você pode fazer coisas como emif (!fread(...))
vez de ter que comparar o resultado com o número de bytes solicitados (o que requer código C extra e código de máquina extra).Provavelmente isso remonta à maneira como a E / S do arquivo foi implementada. (naquela época) Pode ter sido mais rápido gravar / ler arquivos em blocos do que gravar tudo de uma vez.
fonte
Ter argumentos separados para tamanho e contagem pode ser vantajoso em uma implementação que pode evitar a leitura de quaisquer registros parciais. Se alguém fosse usar leituras de byte único de algo como um tubo, mesmo se estivesse usando dados de formato fixo, seria necessário permitir a possibilidade de um registro ser dividido em duas leituras. Se pudesse, em vez disso, solicitar uma leitura sem bloqueio de até 40 registros de 10 bytes cada quando houver 293 bytes disponíveis, e fazer com que o sistema retornasse 290 bytes (29 registros inteiros), deixando 3 bytes prontos para a próxima leitura, ser muito mais conveniente.
Não sei até que ponto as implementações de fread podem lidar com essa semântica, mas certamente poderiam ser úteis em implementações que poderiam prometer suportá-las.
fonte
fread(buffer, 10000, 2, stdin)
e o usuário digita newline-ctrl-D depois de digitar 18.000 bytes, seria bom se a função pudesse retornar os primeiros 10.000 bytes, deixando os 8.000 restantes pendentes para futuras solicitações de leitura menores, mas existem alguma implementação onde isso aconteceria? Onde os 8.000 bytes seriam armazenados durante as solicitações futuras?size
maior que 1, bem ... Para o registro, também pode haver ioctls ou outro absurdo que você pode aplicar ao fluxo para torná-lo me comportar de maneira diferente, não me aprofundei muito.fread
trabalho descrito em tais streams seria útil se houvesse alguma maneira de identificar streams que funcionem dessa maneira.Acho que é porque C não tem sobrecarga de função. Se houvesse algum, o tamanho seria redundante. Mas em C você não pode determinar o tamanho de um elemento do array, você tem que especificar um.
Considere isto:
Se fwrite aceitasse o número de bytes, você poderia escrever o seguinte:
Mas é simplesmente ineficiente. Você terá sizeof (int) vezes mais chamadas de sistema.
Outro ponto que deve ser levado em consideração é que normalmente você não quer que uma parte de um elemento de array seja gravada em um arquivo. Você quer o inteiro inteiro ou nada. fwrite retorna uma série de elementos escritos com sucesso. Então, se você descobrir que apenas 2 bytes baixos de um elemento são escritos, o que você faria?
Em alguns sistemas (devido ao alinhamento), você não pode acessar um byte de um inteiro sem criar uma cópia e deslocar.
fonte