I'm sending a .txt file as an attachment from an Android device using Indy.
When I download this, the .txt file's encoding has changed from UTF-8 to ANSI and is displaying it's content in lines next to eachother instead of underneath eachother.
So what have I been doing wrong, and how to solve this?
Functional code used to send the mail:
Body := TStringList.Create;
IdSMTP := TIdSMTP.Create(nil);
SSLHandler:= TIdSSLIOHandlerSocketOpenSSL.Create(Form1);
IdSMTP.IOHandler:= SSLHandler;
IdSMTP.UseTLS:= utUseExplicitTLS;
IdSMTP.Host := 'smtp.gmail.com';
IdSMTP.Port := 587;
IdSMTP.AuthType := satDefault;
IdSMTP.Username := AppData.MailAddrSender;
IdSMTP.Password := Appdata.MailPassword;
IdMessage := TIdMessage.Create(nil);
IdMessage.From.Name := aName;
IdMessage.From.Address := AppData.MailAddrSender;
IdMessage.Subject := 'E-mail subject';
PathString := System.IOUtils.TPath.Combine(System.IOUtils.TPath.GetDocumentsPath, (PathString + 'Log.txt'));
Body.Add('Mail todays log,');
if FileExists(PathString) then
TIdAttachmentFile.Create(IdMessage.MessageParts,PathString);
try
for I := 0 to Body.Count -1 do
IdMessage.Body.Add(Body.Strings[I]);
IdEmailAddressItem := IdMessage.Recipients.Add;
IdEmailAddressItem.Address := AppData.MailAddrReceiver;
try
IdSMTP.Connect;
try
if IdSMTP.Authenticate then
IdSMTP.Send(IdMessage);
finally
IdMessage.Free;
IdSMTP.Disconnect;
end;
except
on E: Exception do
//exception handling here
end;
finally
IdSMTP.Free;
SSLHandler.DisposeOf;
Body.DisposeOf;
end;
Thank you for your time.
When using
TIdAttachmentFile
, the raw bytes of the file are sent as-is. Indy does not change an attached file's encoding.TIdAttachmentFile
defaults itsContentType
property value based on the extension of the filename that you pass to the constructor. In this case, the extension is.txt
so theContentType
should be defaulting totext/plain
. Thetext/...
media type has acharset
attribute associated with it, but you are not setting the attachment'sCharset
property in your code. Without that, the recipient will interpret the data using a defaultcharset
instead (typicallyus-ascii
per RFC 822). So it is likely that the recipient is detecting thetext/plain
media type with a missingcharset
and is displaying the file data in ASCII/ANSI because it does not know the data is actually UTF-8 encoded instead (since the file is an attachment, the recipient should be saving the raw bytes as-is if saving the attachment to a new file).If you know for a fact that the file you are attaching is encoded in UTF-8, you should be explicit about it:
That sounds more like a linebreak issue than an encoding issue. For instance, if the original file on Android is using
LF
linebreaks, but the recipient only supportsCRLF
linebreaks instead.If you want, you can have Indy normalize the linebreaks to
CRLF
. You would simply load the file data into aTIdText
instead of aTIdAttachmentFile
, and then be sure to set theTIdText.ContentDisposition
property toattachment
(otherwise it will default toinline
), and set theTIdText.FileName
, so the data is still treated as an attachment by the recipient:Now, with all of that said, there are some other minor coding issues with your use of Indy's components in general. I would suggest something more like this instead: