Converter arquivo em Base64String e vice-versa

108

O título diz tudo:

  1. Eu li em um arquivo tar.gz como este
  2. divida o arquivo em um array de bytes
  3. Converta esses bytes em uma string Base64
  4. Converta aquela string Base64 de volta em uma matriz de bytes
  5. Grave esses bytes de volta em um novo arquivo tar.gz

Posso confirmar que os dois arquivos têm o mesmo tamanho (o método abaixo retorna verdadeiro), mas não consigo mais extrair a versão da cópia.

Estou esquecendo de algo?

Boolean MyMethod(){
    using (StreamReader sr = new StreamReader("C:\...\file.tar.gz")) {
        String AsString = sr.ReadToEnd();
        byte[] AsBytes = new byte[AsString.Length];
        Buffer.BlockCopy(AsString.ToCharArray(), 0, AsBytes, 0, AsBytes.Length);
        String AsBase64String = Convert.ToBase64String(AsBytes);

        byte[] tempBytes = Convert.FromBase64String(AsBase64String);
        File.WriteAllBytes(@"C:\...\file_copy.tar.gz", tempBytes);
    }
    FileInfo orig = new FileInfo("C:\...\file.tar.gz");
    FileInfo copy = new FileInfo("C:\...\file_copy.tar.gz");
    // Confirm that both original and copy file have the same number of bytes
    return (orig.Length) == (copy.Length);
}

EDIT: O exemplo de trabalho é muito mais simples (graças a @TS):

Boolean MyMethod(){
    byte[] AsBytes = File.ReadAllBytes(@"C:\...\file.tar.gz");
    String AsBase64String = Convert.ToBase64String(AsBytes);

    byte[] tempBytes = Convert.FromBase64String(AsBase64String);
    File.WriteAllBytes(@"C:\...\file_copy.tar.gz", tempBytes);

    FileInfo orig = new FileInfo(@"C:\...\file.tar.gz");
    FileInfo copy = new FileInfo(@"C:\...\file_copy.tar.gz");
    // Confirm that both original and copy file have the same number of bytes
    return (orig.Length) == (copy.Length);
}

Obrigado!

darkpbj
fonte
Você não pode simplesmente mudar o conteúdo de um arquivo compactado assim. Você terá que descompactar o arquivo na etapa 1 em vez de apenas lê-lo diretamente como está. E então a etapa 5 também terá que recomprimir os dados em vez de apenas gravar os bytes diretamente.
itsme86 de
Felizmente, como não houve manipulação real do arquivo em si (basicamente apenas movendo-o do ponto A para B), esta tarefa em particular não requer nenhuma (de /) compressão
darkpbj

Respostas:

288

Se você deseja, por algum motivo, converter seu arquivo em uma string de base 64. Tipo se você quiser repassar via internet, etc ... você pode fazer isso

Byte[] bytes = File.ReadAllBytes("path");
String file = Convert.ToBase64String(bytes);

E, correspondentemente, leia o arquivo:

Byte[] bytes = Convert.FromBase64String(b64Str);
File.WriteAllBytes(path, bytes);
TS
fonte
Obrigado pela informação, tentei seguir a resposta abaixo, mas não adiantou, mas parecia resolver meu problema com um simples openFileDialog
Senhor SirCode
E se ToBase64String retornar System.OutOfMemoryException? Como você otimiza para arquivos grandes e memória limitada
Olorunfemi Ajibulu
@OlorunfemiAjibulu então eu suspeito, você precisaria usar streams. Ou quebre a corda em partes. Uma vez, escrevi criptografia personalizada para arquivos grandes onde salvamos pedaços criptografados. Adicionamos 4 bytes para salvar o valor inteiro para o tamanho do bloco. Desta forma, sabíamos ler tantas posições
TS
@TaylorSpark interessante. Usei streams e estava bem.
Olorunfemi Ajibulu
3
private String encodeFileToBase64Binary(File file){    
String encodedfile = null;  
try {  
    FileInputStream fileInputStreamReader = new FileInputStream(file);  
    byte[] bytes = new byte[(int)file.length()];
    fileInputStreamReader.read(bytes);  
    encodedfile = Base64.encodeBase64(bytes).toString();  
} catch (FileNotFoundException e) {  
    // TODO Auto-generated catch block  
    e.printStackTrace();  
} catch (IOException e) {  
    // TODO Auto-generated catch block  
    e.printStackTrace();  
}  
    return encodedfile;  
}
hitesh kumar
fonte
3
Embora este código possa responder à pergunta, fornecer contexto adicional sobre como e / ou por que ele resolve o problema melhoraria o valor da resposta a longo prazo. Leia estas instruções para fornecer uma resposta de qualidade.
thewaywere
1
por que, novamente, precisamos javase o OP usa c#?
TS
@TS por que, novamente, precisamos de java?
Clique em Ok