-1
IdFTP_Main.Get('test.ini',MemoryStream);
MemoryStream.Read(Buffer,MemoryStream.Size);
SetString(TempStatus, PChar(MemoryStream.Memory), MemoryStream.Size div SizeOf(WideChar));

test.ini contains a short, plain text string. The memory size in MemoryStream.Size says 8, which is correct. The content of TempString is over a hundred control characters. All help appreciated.

Edit: This code produces the correct file, but requires me to write a copy, which isn't secure:

IdFTP_Main.Get('test.ini',MemoryStream);
MemoryStream.Position := 0;
MemoryStream.SaveToFile('./test.ini');
Charles Barouch
  • 313
  • 2
  • 12

1 Answers1

2

You are treating the stream as though it is UTF-16LE encoded. I suspect that's not the case. You need to determine the encoding. Then use a string stream like this:

var
  Stream: TStringStream;
  Str: string
....
Stream := TStringStream.Create('', TEncoding.UTF8);
try
  IdFTP_Main.Get('test.ini', Stream);
  Str := Stream.DataString;
finally
  Stream.Free;
end;

Or a bytes stream like this:

var
  Stream: TBytesStream;
  Str: string
....
Stream := TBytesStream.Create;
try
  IdFTP_Main.Get('test.ini', Stream);
  Str := TEncoding.UTF8.GetString(Stream.Bytes, 0, Stream.Size);
finally
  Stream.Free;
end;

I've guessed at an encoding. You'll need to substitute the correct encoding.

The call to the stream's Read method makes no sense in this situation. I've just ignored that.

We can't see how you configured the TIdFTP object. Is TransferType set correctly? In order for you to debug this further, use the bytes stream code above and dump the bytes that are downloaded. Check that they match your expectation.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • StringStream got me this text: 'ໜI'#0#0#0#0#0#0#0#0#0#0'⥠À'#0#0#0#0'ֹҰ'#2#1#0#9#0'IsPressed'#0'r'#0'ֹҰ'#2#1#0#$B#0'IsMouseOver'#0'ֹ'#1#0#7#0'躰ָ軐ָ軰ָ輐ָ輰ָ轐ָ轰ָֹҰ'#2#1#0#$B#0'IsMouseOver'#0'ֹҰ'#2#1#0#$B#0'IsMouseOver'#0'ֹҰ'#2#1#0#9#0'IsPressed'#0'r'#0'ֹҰ'#2#1#0#9#0'IsPressed'#0'r'#0'ֹҰ'#2#1#0#$B#0'IsMouseOver'#0'ֹҰ'#2#1#0#9#0'IsPressed'#0'r'#0'ֹȘ'#$008C#$DA00'䋽耀䅙둸¹'#0#0' 䊣'#$DA00'䋽倀䊾'#0#0'ֹ즰'#$008D'澈ু'#$FFFF#$FFFF#0#0#0#0#0#0#0#0#0#0#0'ּֹ즰'#$008D'Õ'#$FFFF#$FFFF#0#0#0#0#0#0#0#0#0#0#0#0'ֹҰ'#2#1#0#$B#0'REST STREAM'#0'ֹҰ'#2#1#0#$A#0'SITE MKDIR'#0#$0A0D'ֹҰ'#2#1#0#$B#0'LANG en-US*'#0'ֹȘ' – Charles Barouch Sep 08 '15 at 06:49
  • You've still not addressed the issue of encoding. Do you understand what a text encoding is? What are the bytes downloaded in the byte stream variant? Do they match the encoding you use? Does this file have a BOM? – David Heffernan Sep 08 '15 at 06:51
  • ByteStrem got me this text: '䕤B'#0#0#4#0#$FDE9#0#8#0#0#0#0#0'➀ɆRR数ɉ'#0#0#2#0#0#0#0#0'➀ɆR䙀Ɇ'#0#0#0#$FF00#0#0#0#0#0#0'➀ɆR䙀Ɇ'#1#0#$FFFF#$FFFF#0'㾀'#0#0#0#0'➀ɆﯔR'#0'䅀꤬ɇ'#0#0'p氀ɂ'#0#0'➀ɆҰ'#2#1#0#5#0'thumb'#0's'#0'➀Ɇᘘ'#$0081#0#0'ഐȽ'#$A#0#1#0#0#0#0#0'➀ɆR䗀Ɇ'#0#0#0#$FF00#0#0#0#0#0#0'➀ɆR䗀Ɇ'#1#0#$FFFF#$FFFF#0'㾀'#0#0#0#0'➀ɆҰ'#2#1#0#5#0'arrow'#0#0#0'➀Ɇ'#$0A80'I'#0#0#0#0#0#0#0#0#0#0'畡瑬➀ɆE䤫`$'#0'ヸո'#$1BF8'ձ'#0#0#0#0'➀ɆҰ'#2#1#0#4#0'text'#0'§'#0#0'➀ɆҰ'#2#1#0#4#0'fill'#0#0#0#0'➀ɆҰ'#2#1#0#7#0'content'#0'➀Ɇ'#$D7C4'd'#0#0#0#0#0#0'蹘ɉ'#0#0#0#0'➀Ɇ'#$0A80'I배Ⱥ锚'#0#0#0'ꀀ'#0#0#0#0#0'➀Ɇ迴d誰d蝘ɉ'#0#0#1#0#0#0#0#0'➀Ɇ迴d誰 – Charles Barouch Sep 08 '15 at 06:52
  • David, I don't know what the source system encoding is. I don't have command line access for the system. – Charles Barouch Sep 08 '15 at 06:53
  • That's not a byte array. That's text. Some encoding implied. What are the first 8 bytes, say, in hex. Read them into a bytes stream. But we are moving away from the question. The code in my answer is accurate. The rest is down to you. – David Heffernan Sep 08 '15 at 06:59
  • What's more, you said you had 8 bytes. You showed a lot more than 8 bytes worth. – David Heffernan Sep 08 '15 at 07:07
  • Source has 8 bytes:^100^200 – Charles Barouch Sep 08 '15 at 07:10
  • Regarding your edit, it's clear that you think this is a code issue but in fact it is a text encoding issue. Once you understand that you'll start making progress. Start by listing those 8 bytes. – David Heffernan Sep 08 '15 at 07:10
  • @RemyLebeau FWIW, look at this edit (http://stackoverflow.com/revisions/32450486/4) I restored the index/size args to GetString because Bytes can be larger than Stream.Size. I think I've got this right? – David Heffernan Sep 08 '15 at 07:20
  • If this is an encoding issue, why does the SavetoFile method produce the exact string? – Charles Barouch Sep 08 '15 at 07:36
  • Because the text editor works out the correct encoding. What is the encoding? Have you worked it out yet? Can you list these 8 bytes? – David Heffernan Sep 08 '15 at 07:43
  • @CharlesBarouch: Because it uses the same encoding for reading and writing. But what are those 8 bytes? Can't be too hard to examine them in the debugger. – Rudy Velthuis Sep 08 '15 at 07:43
  • @Rudy that's not quite right. No encodings are used when reading or writing a memory stream. It's just binary. The text editor that the asker uses decodes the binary to text. – David Heffernan Sep 08 '15 at 07:54
  • FWIW, the StringStream text in your comment looks like pure unused memory (actually, it looks like part of an executable or dcu). But do you really think 8 bytes produce so much junk? – Rudy Velthuis Sep 08 '15 at 07:54
  • @DavidHeffernan: you are right, I forgot to take into account that `TBytesStream` allocates the `Bytes` memory in deltas to reduce the number of reallocations during writes. The `Size` is the actual number of bytes written, and can be less than the `Capacity`. – Remy Lebeau Sep 08 '15 at 07:56
  • @David: you are perfectly right. Haven't had any coffee yet. – Rudy Velthuis Sep 08 '15 at 08:07
  • @CharlesBarouch Are you going to supply those 8 first bytes in the TBytesStream as requested? We are all eagerly waiting! :) – Tom Brunberg Sep 08 '15 at 11:28
  • Once again, the 8 bytes are ^100^200. The carets are shift-6, not a control mark. – Charles Barouch Sep 08 '15 at 22:30
  • Those aren't bytes. Those are characters. We are looking for 8 numbers in the range 00 to ff. – David Heffernan Sep 08 '15 at 22:35
  • @Charles You said earlier that those characters are the *source*, or content of 'test.ini'. We want to know the 8 first *bytes* in the *TBytesStream* immediately after the call to `IdFTP_Main.Get('test.ini', Stream);`. And also let us know what `Stream.Size` is. – Tom Brunberg Sep 09 '15 at 01:04
  • Tom, scroll up. It's in the comments already. It says 8 bytes, but I'm getting hundreds. – Charles Barouch Sep 09 '15 at 14:33
  • Why can't you show us these 8 bytes? We want 8 numbers in the range 0 to 255. – David Heffernan Sep 09 '15 at 14:39
  • @Charles Well, then I can only conclude that Davids conversion of stream bytes to a string works perfectly, and you don't have a problem anymore. Cheers! Regarding 'getting hundreds', that must be something you do wrong, but you don't want help from us. – Tom Brunberg Sep 09 '15 at 15:20