2012-01-07 3 views
2

Я Двоичные функции Base64, что вы ответили: Binary to Base64 (Delphi)Base64 в двоичном (Delphi)

Я успешно кодировать файл в base64 строку и записать его в базу данных MsSQL2008, но я хочу задать вопрос: Как могу ли я записать этот файл на диск с помощью EncdDecd.pas?

+0

В принятом ответе, он говорит о 'функции DecodeBase64'. Вы посмотрели на него? Если да, то как далеко вы добрались, и с какими проблемами вы столкнулись? –

+0

Да, я ищу его точно, но я не знаю, как его использовать. Можете ли вы написать функцию, как в принятом ответе, для восстановления этого файла из кодированного base64 и записи его на диск? – user1135768

+3

Опять же, что вы пробовали, как далеко у вас? Вы не сможете многому научиться, просто используя код ложки. –

ответ

6

Эта функция использует строчную кодировку base64, декодирует ее и записывает полученный массив байтов в файл.

procedure DecodeToFile(const base64: AnsiString; const FileName: string); 
var 
    stream: TFileStream; 
    bytes: TBytes; 
begin 
    bytes := DecodeBase64(base64); 
    stream := TFileStream.Create(FileName, fmCreate); 
    try 
    if bytes<>nil then 
     stream.Write(bytes[0], Length(Bytes)); 
    finally 
    stream.Free; 
    end; 
end; 

Чтобы объяснить, что здесь происходит, первую линию

bytes := DecodeBase64(base64); 

выполняет декодирование и возвращает декодированное двоичное содержимое файла в TBytes переменном. TBytes - это просто массив байтов.

Следующим шагом является создание файла. Идиоматическим способом записи файлов в Delphi является использование потоков. В этом случае мы хотим получить номер TFileStream.

stream := TFileStream.Create(FileName, fmCreate); 

fmCreate опция означает, что, если файл уже существует, он будет заменен и переписан, что мы пишем.

Заключительный шаг, чтобы записать содержимое массива байт в файл

if bytes<>nil then 
    stream.Write(bytes[0], Length(Bytes)); 

if bytes<>nil проверки обрабатывать случай, когда base64 строка декодирует пустой массив. Если бы мы удалили эту проверку, следующая строка привела бы к ошибке во время выполнения, если бы вы работали с включенным контролем диапазона (что вы должны делать). Призыв к stream.Write должен быть понятным.

+0

Он отлично работает. Спасибо. – user1135768

+0

Было бы неплохо видеть, что это отмечено как принятый ответ. – TomC

13

Как всегда, Дэвид отвечал достаточно. Хотя я не могу устоять, чтобы дать немного другое решение, используя некоторые из плюсов от недавних версий Delphi.

procedure DecodeFile(const base64: AnsiString; const FileName: string); 
var 
    stream: TBytesStream; 
begin 
    stream := TBytesStream.Create(DecodeBase64(base64)); 
    try 
    stream.SaveToFile(Filename); 
    finally 
    stream.Free; 
    end; 
end; 
+3

+1 Это более чистый способ сделать это. Пожалуйста, продолжайте не сопротивляться соблазну дать альтернативные и лучшие ответы! –

0

У меня есть очень старый Delphi2006 (v10.0.2558.35231 Update 2) и должен был декодировать base64 UTF8 кодированные входные строки. Я, наконец, понял это, и это пример для всех, кого это интересует.

Uses 
    IdCoderMIME; // Indy9 
    var 
    decoder: TIdDecoderMIME; 
    str: WideString; 
    - - - 

    decoder := TIdDecoderMIME.Create(nil); 
    str := base64DecodeUTF8(decoder, b64sourcestr); 
    decoder.Free; 
    - - - 

    function base64DecodeUTF8(decoder:TIdDecoderMIME; str:String): WideString; 
    var 
    stream:TMemoryStream; 
    utf8: UTF8String; 
    //idx:Integer; 
    begin 
    stream := TMemoryStream.Create; 
    try 
     decoder.DecodeToStream(str, stream); 
     setString(utf8, PChar(stream.Memory), stream.Size); 
     Result := UTF8Decode(utf8); 
     //for idx := 0 to stream.Size-1 do begin 
     // Writeln(PChar(stream.Memory)[idx] + ' ' + IntToStr(ORD(PChar(stream.Memory)  [idx]))); 
     //end; 
    finally 
     stream.Free; 
    end; 
    end; 
+1

'TIdDecoderMIME' имеет статический' DecodeStream() 'метод, поэтому вам не нужно создавать экземпляр объекта' TIdDecoderMIME'. Вы можете удалить переменную 'decoder' и заменить' decoder.DecodeToStream (str, stream); 'с' TIdDecoderMIME.DecodeStream (str, stream); вместо этого. Или вы можете использовать статический метод 'TIdDecoderMIME.DecodeString()', который имеет параметры для указания кодировки двоичных данных при декодировании его в строку Unicode и кодировку выходной строки при преобразовании строки Unicode в Ansi (D2007 и ранее). –

1
uses 
    Soap.EncdDecd; 

function TForm1.EncodeFile(const FileName: string): AnsiString; 
var 
    MemStream: TMemoryStream; 
begin 
    MemStream := TMemoryStream.Create; 
    try 
    MemStream.LoadFromFile(Filename); 
    Result := EncodeBase64(MemStream.Memory, MemStream.Size); 
    finally 
    MemStream.Free; 
    end; 
end; 

function TForm1.DecodeFile(const base64: AnsiString): TBytesStream; 
begin 
Result := TBytesStream.Create(DecodeBase64(base64)); 
end; 
0

Посмотрев в Soap.EncdDecd тот может найти более независимую от платформы пути, так как это DecodeBase64 использует универсальные (без AnsiString) метод из System.NetEncoding.

на основе образца Уве:

uses 
    ... 
    System.Classes, 
    System.NetEncoding; 

... 
procedure DecodeFile(const base64: String; const FileName: string); 
var 
    stream: TBytesStream; 
begin 
    stream := TBytesStream.Create(TNetEncoding.Base64.DecodeStringToBytes(base64)); 
    try 
    stream.SaveToFile(Filename); 
    finally 
    stream.Free; 
    end; 
end; 
Смежные вопросы