Copiar arquivo binario [RESOLVIDO]

1. Copiar arquivo binario [RESOLVIDO]

Matheus Gomes
matheusgf1539

(usa Ubuntu)

Enviado em 09/03/2017 - 08:37h

Bom dia pessoal estou com muita dificuldade, pra fazer um trabalho escolar, possuo um projeto pra fazer em C# que tenha como função copiar um arquivo de uma maquina pra outra via Socket, conseguir fazer esse programa para copiar localmente, com a utilização de um laço while. porém quando eu passo os dados lidos para outra maquina encontro o problema que o arquivo sai corropido. gostaria de saber outra forma de copiar todo o meu arquivo sem o uso de um laço de repetição se é que é possivel.
meu codigo
void main(){
FILE* origem = fopen("/home/matheus/Imagens/img.png","rb");
FILE* destino = fopen("/home/matheus/Documentos/img.png", "wb");

unsigned char B64; // Variavel de 64 bits

while(!feof(origem)) {

fread (&B64, sizeof(unsigned char), 1, origem);
fwrite(&B64, sizeof(unsigned char ), 1, destino);
}
fclose(origem);
fclose(destino);


  


2. Re: Copiar arquivo binario

Uilian Ries
uilianries

(usa Linux Mint)

Enviado em 09/03/2017 - 09:34h

Existem funções por plataforma que fazem ou a cópia inteira, ou ajudam nisso.

No Windows, você tem CopyFile[1], que consegue copiar tudo numa única função.
Enquanto no Linux, você pode utilizar sendfile[2] ou splice[3], mas ambas não darão a solução pronta, você irá precisar trabalhar mais algumas linhas pra usá-las.

Existem algumas bibliotecas para C++ portáveis que possuem esta funcionalidade já implementada,
a biblioteca Boost possui a função copy_file[4], enquanto a Poco utiliza copyTo[5].

Em C, você pode utilizar Gnome lib, ela possui a função g-file-copy[6], que copia o arquivo todo.

[1] https://msdn.microsoft.com/en-us/library/windows/desktop/aa363851(v=vs.85).aspx
[2] https://linux.die.net/man/2/sendfile
[3] https://linux.die.net/man/2/splice
[4] http://www.boost.org/doc/libs/1_53_0/libs/filesystem/doc/reference.html#copy_file
[5] https://www.appinf.com/docs/poco/Poco.File.html
[6] https://developer.gnome.org/gio/stable/GFile.html#g-file-copy


3. Copiar arquivo binario

Matheus Gomes
matheusgf1539

(usa Ubuntu)

Enviado em 09/03/2017 - 10:01h

agradecido obrigado pelas dicas.


4. Re: Copiar arquivo binario [RESOLVIDO]

Paulo
paulo1205

(usa Ubuntu)

Enviado em 09/03/2017 - 10:35h

matheusgf1539 escreveu:

Bom dia pessoal estou com muita dificuldade, pra fazer um trabalho escolar, possuo um projeto pra fazer em C#


C#? O programa que você mostrou é em C, não C#.

Nesta comunidade do VoL, o foco é C e C++, não C#. Deve haver outras sobre Mono e C#, onde talvez você consiga ajuda mais específica sobre C#.

Como o programa mostrado tem cara de C, vou continuar respondendo como se C fosse.

ue tenha como função copiar um arquivo de uma maquina pra outra via Socket, conseguir fazer esse programa para copiar localmente, com a utilização de um laço while. porém quando eu passo os dados lidos para outra maquina encontro o problema que o arquivo sai corropido. gostaria de saber outra forma de copiar todo o meu arquivo sem o uso de um laço de repetição se é que é possivel.
meu codigo
void main(){ 


Aqui há um erro. O tipo de retorno de main() tem de ser void.

Também a lista de argumentos de main() pode ter um problema. Se você estiver usando C++, tudo bem usar desse jeito. Mas se for C, então você tem de dizer que a função não recebe argumentos através da palavra-chave void presente entre os parênteses pois, ao contrário do C++ (e Java, e C#), uma lista de argumentos vazia em C significa que a função poderá ser chamada com qualquer quantidade de argumentos de quaisquer tipos.

FILE* origem = fopen("/home/matheus/Imagens/img.png","rb");
FILE* destino = fopen("/home/matheus/Documentos/img.png", "wb");


Eu sou um ardoroso defensor de testar o sucesso de qualquer operação de entrada e saída, principalmente no caso da obtenção inicial dos descritores ou ponteiros de arquivos ou streams.

Eu mudaria o código acima para algo como o seguinte.

  FILE *origem, *destino;
if(!(origem=fopen("/home/matheus/images/img.png", "rb"))){
perror("Não pude abrir arquivo de leitura");
return 1;
}
if(!(destino=fopen("/home/matheus/images/Documents/img.png", "rb"))){
perror("Não pude abrir arquivo de saída");
return 1;
}


unsigned char B64; //            Variavel de 64 bits 

while(!feof(origem)) {

fread (&B64, sizeof(unsigned char), 1, origem);
fwrite(&B64, sizeof(unsigned char ), 1, destino);
}


Todo o laço de repetição também não está do meu agrado, e com erro.

A função feof() só retorna verdadeiro depois de uma operação de leitura exceder a quantidade de dados presente na fonte. Como você está lendo um caráter de cada vez, esse “depois de exceder” só vai acontecer depois que você mandar ler um byte e receber uma sinalização da função dizendo que só pôde ser zero bytes. Só que você despreza essa sinalização, pois não testa o valor de retorno da função.

Em tempo: se for para ler caráter a caráter, por que não usar simplesmente fgetc(), em lugar de fread()? Se for para usar fread(), seria melhor ler blocos de caracteres de uma vez só, para diminuir a quantidade total de chamadas a função.

Eis como eu reimplementaria todo o bloco acima.

  char buffer[4096];
size_t nread;

/* É seguro usar ‘1’ abaixo porque sizeof(char) é 1 por definição. */
while((nread=fread(buffer, 1, sizeof buffer, origem))>0)
if(fwrite(buffer, 1, nread, destino)<nread){
perror("Erro de gravacao");
return 1;
}
if(ferror(origem)){
perror("Erro de leitura");
return 1;
}


fclose(origem);
fclose(destino);


Também a chamada a fclose() pode falhar, particularmente aquela do stream de saída. Assim sendo, ela deveria testada.

  if(fclose(destino)!=0){
perror("Erro de gravacao");
return 1;
}







Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts