Unable to write to a file

Hi,

I’m writing to a file using code is shown below. File is opened but bool success = tempFile.overwriteTargetFileWithTemporary(); returns false and the text is not written to the file. I’m not sure why. Please help!

    String content;
    File resourceFile = File::getCurrentWorkingDirectory().getChildFile("file.txt");
    TemporaryFile tempFile(resourceFile);
    FileOutputStream output(tempFile.getFile());
    if (!output.openedOk())
    {
        DBG("FileOutputStream didn't open correctly ...");
        // ... some other error handling
    }
    output.setNewLineString("\n");

    output.writeText("Some text", false, false, nullptr);

    output.flush(); // (called explicitly to force an fsync on posix)
    content = "flush";
    if (output.getStatus().failed())
    {
        content = "An error occurred in the FileOutputStream";
        DBG("An error occurred in the FileOutputStream");
        // ... some other error handling
    }
    else {
        content = "No Error";
    }

    bool success = tempFile.overwriteTargetFileWithTemporary();
    
    if (success) {
        content = "Success";
    }
    else {
        content = "Failure";
    }

I think you need to destroy the output stream before trying to do that. Having a stream opened on a file may lock it. So maybe allocate it as a unique pointer and reset it appropriately.

That being said, we had this issue recently on one machine on Windows, even though no stream was opened in the code.
What was happening is that some file search software was running in the background. The result was that the temporary file was created, then the background software was indexing it, and then while indexing was happening tempFile.overwriteTargetFileWithTemporary() was called and of course failing because this other software had the temp file locked.

Of course, closing this background software worked but as this is something that could happen on a client machine, our fix is to add a sleep call if it fails to retry after some time (I think we picked 1sec). It’s not great and could still fail in theory but so far so good.

Thank You @dimbouche , I changed the code to the following and it worked :tada:

    File resourceFile = File::getCurrentWorkingDirectory().getChildFile("file.txt");
    if (auto output = std::unique_ptr<juce::FileOutputStream>(resourceFile.createOutputStream()))
    {
        output->setPosition(0);
        output->truncate();
        output->writeText("Text 1", false, false, nullptr);
        output->setNewLineString("\n");
        output->writeText("Text 2", false, false, nullptr);
        output->setNewLineString("\n");
        output->writeText("Text 3", false, false, nullptr);
        output->setNewLineString("\n");
    }

Text is written to the file.

A Question - I was expecting

Text 1
Text 2
Text 3

But the output is
Text 1Text 2Text 3

I don’t understand why output->setNewLineString("\n"); doesn’t add new line. Any idea ?

setNewLineString is not adding a new line. It is just telling the output stream what it should write in the file when your text has a new line.

You should only call it once, and only if you want a custom new line character (not “\n”).

In your case you do not want to call it. And you want to add the new line manually by either appending it to your text (change “Text 1” to “Text 1\n”) or by calling writeText separately with “\n”.

Thank You @dimbouche.