File replaceWithText question


#1

Folks,

Trying to write a simple juce application to change a substring within a text file. It looks like the word gets replaced, but when I call File::replaceWithText(), there are extra bytes inserted into the text file, and the file can’t be parsed properly. Perhaps I am just not understanding the correct usage of File::replaceWithText.

File configText;
configText = T("config.txt");
if(configText.existsAsFile()) 
{

   // load current config.txt into memory as a String
   String currentConfig = configText.loadFileAsString();

   // print the current string length before doing anything
   int len = currentConfig.length();
   printf("currentConfig len:  %d\n",len);

   // change substring within string
   String newConfig = currentConfig.replace(T("text1"),T("text2"),0);

   // print new string length
   len = newConfig.length();
   printf("newConfig len:  %d\n",len);
                                
   // write new config.txt to a new file                         
   configText.replaceWithText(newConfig);
                           
   // now print the new file length - somehow the file size increases     
   int filelen = configText.getSize();
   printf("filelen:  %d\n",filelen);
}

This is a simple 18 line file. After running the application, the file still contains 18 lines and looks identical to the human eye, but the size increases from 463 bytes to 481, as shown below. It appears that the file size is increasing after the File::replaceWithText() but the String::replace() is not increasing the size of the file:

src# ./testapp
currentConfig len: 463
newConfig len: 463
filelen: 481
src#


#2

I’m guessing it’s changing single byte line endings (cr), with two byte line endings (cr/lf)… which makes sense based on the extra data being 18 bytes, which equals the number of lines in the file. looking at it in a hex editor would verify this.


#3

Good guess, man, cpr. You were right. Viewed in a hex editor and there are extra 0d 0a bytes at the end of each line. The file before modification just has 0a at the end of some lines.

I will study to see if I can get around filtering out these cr/lf 0d 0a bytes using juce and still be able to use File::replaceWithText().

P.S. My platform is Ubuntu 9.10 Linux.

Jason


#4

After much pain and frustration and peaking into the File members that wrote text strings, I finally found the resolution. I was trying to write a string to a text file using the File members when I should have used FileOutputStream members. So I used the << operator with my FileOutputStream and the text String variable. It was the following:

virtual OutputStream& OutputStream::operator<< ( const String& text)

When I tried to use File::appendText and File::replaceWithText members, the CR/LF extra byte of 0D would show up at the end of each line, if the string was more than one line (it worked when the string was only one line and no \n CR existed). Interestingly enough, the OutputStream::writeString(const String & text) member would still write the extra CR/LF “0Dx” byte - I still don’t know why this OutputStream member didn’t work properly, but the << operator did.

I will post this as a code example in the linux section, to help anyone who is trying to edit a text file in Linux. I’m sure the CRLF behavior can be a little bit annoying to get around for newbies.