3

I found legacy source code and here excerpt -

TMemoryStream *DFile = new TMemoryStream;
TFileStream*BFile = new TFileStream;

Here are the some official documented data for above classes:


  • Is TMemoryStream & TFileStream has same purpose ?

  • If we consider binary data output streaming for awhile then can we replace TMemoryStream & TFileStreamwith std::ostream & std::ofstream respectively?

  • (I am bit of confused) When to use compiler specific TMemoryStream & TFileStreamover std::ostream & std::ofstream respectively?

    • What advantages, that we can gain if we carried out above thing?
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
Buddhika Chaturanga
  • 957
  • 2
  • 14
  • 29
  • There are no direct standard C++ equivalents as we don't know what those 3rd party classes are. There are multiple levels of inheritance with `TObject` being the base class. There is no equivalent of `TObject` in standard C++. – Ron Mar 06 '18 at 15:50
  • @Ron for `TMemoryStream ` they mentioned `"Use TMemoryStream to store data in a dynamic memory buffer that is enhanced with file-like access capabilities"` ... dynamic memory ? Isn't `std::ofstream` doing that? – Buddhika Chaturanga Mar 06 '18 at 15:52
  • There is no direct equivalent as there can't be a direct equivalent because VLC is not a Standard C++ Library. – Ron Mar 06 '18 at 15:53
  • @Ron I got it... here I am bit of struggling , we can emulate those by using `std::ofstream` or `std::ostream` right ? – Buddhika Chaturanga Mar 06 '18 at 15:56
  • 2
    In other words, you found some C++Builder code but don't know exactly how to convert it to plain standard C++? – Rudy Velthuis Mar 06 '18 at 19:55
  • @RudyVelthuis ,I am trying to replace it by `std::filebuf` – Buddhika Chaturanga Mar 06 '18 at 19:56
  • @Ron: It's called VCL (Visual Component Library) and neither TMemoryStream nor TFileStream are part of it. But they are part of the Delphi (Object Pascal) runtime library to which C++Builder can link too. – Rudy Velthuis Mar 06 '18 at 19:58
  • @BuddhikaChaturanga: In C++Builder or in plain standard C++? And a `std::filebuf` is not a good equivalent. A file buffer is simply a buffer for a *file*, but a memory stream is an (expandable) block of memory which can be accessed *as if it were a file*, i.e. you can write or read sequentially, you can `seek()` etc. The more you append to it, the larger the memory block gets (just like a file grows if you append to it), etc. That is not the same as a `std::filebuf`. The closest equivalent is probably a `std::stringstream`, indeed. – Rudy Velthuis Mar 06 '18 at 20:02
  • @RudyVelthuis,Is it wise to operate `std::stringstream` in binary mode? regarding binary file output ... – Buddhika Chaturanga Mar 06 '18 at 20:11
  • @BuddhikaChaturanga: `std::stringstream` is not an exact equivalent, just something close. I don't think it would make sense. I don't know a *direct* equivalent. – Rudy Velthuis Mar 06 '18 at 20:15
  • @RudyVelthuis if you don't mind , what would be the better option from `std::ofstream` ,`std::ostream `and` std::filebuf` – Buddhika Chaturanga Mar 06 '18 at 20:17
  • 1
    Take a look here: https://stackoverflow.com/questions/1559254/are-there-binary-memory-streams-in-c – Rudy Velthuis Mar 06 '18 at 20:18
  • @RudyVelthuis `reinterpriting ` bad isn't it ? I know it works,but Rudy .. did you check the 2nd answer here that Remy given,`TMemoryStream writes to a block of memory that is dynamically (re)allocated as needed`,can we achieved it using `std::stringstream` – Buddhika Chaturanga Mar 06 '18 at 20:24
  • In older versions of C++Builder (as late as 2013 though, IDK when/if it was finally fixed), their standard library implementations of `ostream` and descendents are bugged to read uninitialized memory and give runtime exceptions sometimes. So I would not really recommend changing the code if you are continuing to use their compiler. (Obviously if you are porting to g++ or something then you will need to change the code) – M.M Mar 06 '18 at 20:54
  • @M.M right now I am porting old Borland code into modern C++17 (msvc).I have to replace these legacy codes in order to maintain portability.M.M do you have any suggestions about best option? – Buddhika Chaturanga Mar 06 '18 at 21:29
  • @BuddhikaChaturanga if your code use visual components then you will have a hard time porting this as both `TMemoryStream` and `TFileStream` where usually used by them for example for converting fileformat of images in memory and more ... but that depends on how your app using it. So you would end up writing wrappers for each component you port as 3th party libs doing the same stuff usually not work with streams. If your code just used it to ease up the maintenance of own memory and files than it should be portable relatively easy. – Spektre Mar 07 '18 at 09:31
  • @BuddhikaChaturanga: I have no idea what you mean with "reinterpriting bad isn't it ?". Did you actually read the question and answers I linked to? It clearly explains how you can use a stringstream to more or less replace a TMemoryStream. That was your question. If you have more questions, ask a new one. – Rudy Velthuis Mar 08 '18 at 20:32
  • @BuddhikaChaturanga: It would be much easier to answer your question if you showed a little for what these Delphi stream types are used, i.e. showed some of the code that actually used them. Now we can just guess which classes are best to replace them. – Rudy Velthuis Mar 08 '18 at 20:35
  • @RudyVelthuis ,the owner of legacy code has intention store data in a memory and finally he used that memory buffer to write in to a file,like we store set of data in `std::vector` and finally write those data in to a file using that vector. likewise., problem is how to construct such raw data stream without mentioning a `filename`(`std::srtingstream` shuold be neglected here) , at least we can store them in `std::vector` and finaly iterate it and write to a file. – Buddhika Chaturanga Mar 09 '18 at 10:11
  • Why should std::(o)stringstream be neglected here? – Rudy Velthuis Mar 09 '18 at 18:12
  • @RudyVelthuis `std::stringstream` reperesents `Text` rather than raw `binary` stream ? am I wrong ? – Buddhika Chaturanga Mar 11 '18 at 05:00
  • @Buddhika: Did you actually read the link I posted? – Rudy Velthuis Mar 11 '18 at 14:21
  • @RudyVelthuis Thank you for your support, I tried with stringstream but couldn't achieved what I expected Rudy, – Buddhika Chaturanga Mar 11 '18 at 20:04
  • @Buddhika: people would be much more able to help you if you posted a [MCVE] and if you would actually read what people tell you. Now, you are in your own way. Again: https://stackoverflow.com/a/1559584/95954 – Rudy Velthuis Mar 11 '18 at 22:22
  • @RudyVelthuis don't misunderstand, I already tried that friend,couldn't achieved what I expected,also you know senior people,they don't like to see `reinterpret_cast`,I don't know why.. even there is a tool exist for the purpose ,they don't like to use it, calling `bad` `unsafe` , :( – Buddhika Chaturanga Mar 12 '18 at 06:11
  • 1
    FWIW, I am a senior person, and I don't mind a cast when a cast makes sense. – Rudy Velthuis Mar 12 '18 at 12:19
  • @RudyVelthuis can you check this article, since you are a senior person,it's highly valuable your verification on it. https://www.codeproject.com/Tips/808776/Cplusplus-Simplistic-Binary-Streams – Buddhika Chaturanga Mar 13 '18 at 07:46
  • I only skimmed it, but the solution looks fine. I like the fact that they remain low level and just store what you give them. – Rudy Velthuis Mar 13 '18 at 12:46
  • @RudyVelthuis thank you very much,by the way his underlying store is nothing but a `std::vector`, do you recommend his approach ? I am testing it,haven't found any issues yet.Initially I was trying to build something like that using `std::vector`,but I was afraid and scared to do that,but now I am fine with that,because some one has done it pretty well. :) – Buddhika Chaturanga Mar 13 '18 at 13:48

2 Answers2

4

Is TMemoryStream & TFileStream has same purpose ?

They have a similar interface, but they have different purposes. TMemoryStream read/writes data from/to a block of memory. TFileStream reads/write data from/to a file instead.

If we consider binary data output streaming for awhile then can we replace TMemoryStream & TFileStream with std::ostream & std::ofstream respectively?

TFileStream writes to a file. std::ofstream writes to a file. So, you can replace TFileStream with std::ofstream, yes.

TMemoryStream is a little bit trickier. TMemoryStream writes to a block of memory that is dynamically (re)allocated as needed. There is no standard C++ stream for writing to a block of dynamic memory. Unless you consider std::ostringstream, which is meant for outputting strings, not binary data. Or std::vector<char>, which is dynamic, but doesn't have a stream interface.

However, std::ostream can work with just about any std::streambuf you want, and there are plenty of 3rd party custom std::streambuf implementations that can be used to read/write from/to (dynamic) memory. For example, this one writes to a std::array<char, N>, but you can adapt it to write to a std::vector<char> instead. Or find another implementation that suits your needs. Or write your own.

When to use compiler specific TMemoryStream & TFileStream over std::ostream & std::ofstream respectively?

Use TMemoryStream/TFileStream when you need to directly interface with Borland/Embarcadero's RTL/VCL/FMX frameworks. You should use standard C++ classes otherwise.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • Thank you, I saw that site earlier, problem is cannot bring 3rd party stuff bro.. yeah I will implement my own functionality..., , – Buddhika Chaturanga Mar 06 '18 at 20:21
  • Remy problem is.. I have to convert these old school borland stuff to `std` modern stuff(concerning portability),that's why I am struggling .. hope you can understand my situation :) – Buddhika Chaturanga Mar 06 '18 at 20:27
1

Streams are part of C++ IO library. In particular, files streams are supported by std::fstream (http://en.cppreference.com/w/cpp/io/basic_fstream), and in-memory stream is represented by std::stringstream (http://en.cppreference.com/w/cpp/io/basic_stringstream)

SergeyA
  • 61,605
  • 5
  • 78
  • 137
  • oh .. is it wrong to use `std::ostream` instead of `std::stringstream` as the replacement of `TMemoryStream `? – Buddhika Chaturanga Mar 06 '18 at 15:47
  • std::ostream is the abstract class that stringstream and fstream implement – UKMonkey Mar 06 '18 at 15:54
  • @UKMonkey this is not true. `std::ostream` is not an abstract class. – SergeyA Mar 06 '18 at 15:57
  • @BuddhikaChaturanga I would not say it's wrong, it's just doesn't give you much in term of functionality. – SergeyA Mar 06 '18 at 15:58
  • thank you for the info,I will go with `std::ofstream` then .. it's a convenient and safe.. Sergey, only doubt it that `dynamic memory` part that they have mentioned in wiki. – Buddhika Chaturanga Mar 06 '18 at 16:01
  • @BuddhikaChaturanga what exactly is your doubt here? – SergeyA Mar 06 '18 at 16:03
  • as I mentioned @Ron ,in Borland wiki they mentioned -> `"Use TMemoryStream to store data in a dynamic memory buffer that is enhanced with file-like access capabilities"` for `TMemoryStream `.. – Buddhika Chaturanga Mar 06 '18 at 16:07
  • @BuddhikaChaturanga but what does it mean **for you**? – SergeyA Mar 06 '18 at 16:14
  • @BuddhikaChaturanga You can't use `std::ofstream` to write to dynamic memory, only to a file. For writing to dynamic memory, you need `std::ostream` with a memory-based `std::streambuf`. Or `std::ostringstream` if you don't mind storing binary data in a `std::string`, which it is not intended for. – Remy Lebeau Mar 06 '18 at 22:07
  • @RemyLebeau thank you for the info',if you don't mind can you post a link how to do dynamic alloc using `std::streambuf` please? – Buddhika Chaturanga Mar 06 '18 at 22:10
  • @BuddhikaChaturanga `std::streambuf` itself doesn't support that directly. You have to write your own `std::streambuf` derived class (or find a 3rd party one) that does what you need. I suggest you read the `std::streambuf` documentation to know how it works and what you need to override/implement from it. There are plenty of tutorials for writing custom `std::streambuf` classes if you look around. – Remy Lebeau Mar 06 '18 at 22:17
  • I am not sure we are on the right track here. I am still not following the emphasis on **dynamic** memory here. How would you like to use the stream? After you write data to it, what are you intending to do with it? – SergeyA Mar 06 '18 at 22:44