-2

I'm having a problem creating a txt file on C#. I am trying to create this file in memory (I don't want to create it in a physical path) and then open this file programmatically with the defaul app. The PC must detect the file extension (in this case .txt) and choose the right program to display the file (in this case maybe Notepad, Word, Wordpad...).

I got this now:

using (var writer = new StreamWriter("file.txt"))
{
    writer.WriteLine(
        grr[0].Keys.ToArray()[0] + "," + grr[0].Keys.ToArray()[1] + "," +
        grr[0].Keys.ToArray()[2] + "," + grr[0].Keys.ToArray()[3]);

    for (int r = 0; r < row - 1; r++)
    {
        writer.WriteLine(
            grr[r].Values.ToArray()[0] + "," + grr[r].Values.ToArray()[1] + "," +
            grr[r].Values.ToArray()[2] + "," + grr[r].Values.ToArray()[3]);
    }
}

But I don't know how to open this file.

Massimiliano Kraus
  • 3,638
  • 5
  • 27
  • 47
Luis Acuña
  • 111
  • 2
  • 7
  • 1
    Huh? In the code you share, `new StreamWriter("file.txt")` creates a new file in the application's working directory. You can't have it both ways. Either you create a file and it has a physical path, or you don't create a file. – adv12 May 31 '17 at 21:46
  • Look at https://stackoverflow.com/questions/1232443/writing-to-then-reading-from-a-memorystream for creating a streamwriter to a memorystream and then reading it later. – Joe May 31 '17 at 21:46
  • 2
    If you just want an in-memory stream (i.e. not a file at all), look into the [MemoryStream class](https://msdn.microsoft.com/en-us/library/system.io.memorystream(v=vs.110).aspx). – adv12 May 31 '17 at 21:47
  • 1
    ...but then you can't open an in-memory stream in another application. Seems like you have conflicting requirements. – adv12 May 31 '17 at 21:48
  • you want to create a file system in memory if you want have a name and text. – jdweng May 31 '17 at 21:50
  • yes, i am using new streamwriter("file.txt") but this do not helps me, thats why i am asking for help, i need another solution. I just want to create a txt file "in memory" and then display this file maybe with notepad, wordpad, word, etc.. (a Default application to open txt files) – Luis Acuña May 31 '17 at 21:53
  • 1
    There is no such thing as what you are trying to achieve. – adv12 May 31 '17 at 21:56
  • @LuisAcuña, let me guess... When you use Notepad and you create a new document, it is not stored on disk, but you can modify it. It is stored physically only when you save it. And this is exactly what you want: create a file that an app like Notepad can open without having stored it before on disk. Am I correct? – Massimiliano Kraus May 31 '17 at 22:05
  • Yes, that's what I am trying to do @massimiliano – Luis Acuña May 31 '17 at 22:08
  • Let's rephrase your question, *"how do I get a 3rd party program, that is only designed to only open text files from the disk, to display a string from the memory of my program without saving a file to the disk"*. Do you understand now why your question is hard to answer? This sounds like a [XY problem](https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem), please describe what you are trying to do that opening a file like this is the solution. – Scott Chamberlain Jun 01 '17 at 01:11
  • You could use UIAutomation to open up the text writer first and then send your in-memory text there – kurakura88 Jun 01 '17 at 02:10

2 Answers2

1

You want a file system in memory that contains filename and data. So use something like this:

public class MyFolder
{
    string folderName { get; set;}
    List<MyFolder> childFolders { get; set; }
    Dictionary<string, List<byte>> files { get; set; }
}
Massimiliano Kraus
  • 3,638
  • 5
  • 27
  • 47
jdweng
  • 33,250
  • 2
  • 15
  • 20
0

Ok, the only solution I see is quite a hack:

  1. Write the data on a file;
  2. Open the file with the default app using Process.Start;
  3. Delete the file with File.Delete.

Code:

// test data that I'll write on the file
var text = Enumerable.Range(0, 1000000).Select(x => x.ToString()).ToArray();

// choose the Desktop folder to verify that
// the file is deleted at the end of the method
var tempDir = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);

// choose a random file name that will be unique 99.999999999% of the times
var filePath = Path.Combine(tempDir, Guid.NewGuid().ToString() + ".txt");

// write the file. Here I use WriteAllLines, you can use StreamWriter
File.WriteAllLines(filePath, text);

// start the default app for this path
Process.Start(filePath);

// wait to let the default app to open the file;
// otherwise the app will crash, not finding the file anymore
// just in the middle of the read
// (I put 2 sec, but the time must be verified
// depending on your system and the file size) 
Thread.Sleep(2000);

// this will totally delete the file
File.Delete(filePath);

If you have Notepad as default app for txt files, that's what you'll see: Notepad opens up with your data, but the file doesn't exist anymore. That's quite what you wanted, isn't it? You won't find the file in the Recycle Bin neither, so you won't have disk space leaks.

The only defect of this trick is: if you click "Save" on your app, it won't ask you the path where you want to save the file. Instead, it will simply re-create the file as it was before deletion, and will save the data directly. That's because it opened a physical file, it didn't created a new one, so it remembers the filePath and will use it to save.

If you don't find more correct/professional solutions, this one can do its job.


ASIDE:

I'd suggest to you a little refactoring.

First step, avoid repetitions:

using (var writer = new StreamWriter("file.txt"))
{
    var array = grr[0].Keys.ToArray();
    writer.WriteLine(array[0] + "," + array[1] + "," + array[2] + "," + array[3]);

    for (int r = 0; r < row - 1; r++)
    {
        var grrr = grr[r].Values.ToArray();
        writer.WriteLine(grrr[0] + "," + grrr[1] + "," + grrr[2] + "," + grrr[3]);
    }
}

Second step, use more advanced built-in functions:

using (var writer = new StreamWriter("file.txt"))
{
    writer.WriteLine(string.Join(",", grr[0].Keys.ToArray()));

    for (int r = 0; r < row - 1; r++)
    {
        writer.WriteLine(string.Join(",", grr[r].Values.ToArray()));
    }
}
Massimiliano Kraus
  • 3,638
  • 5
  • 27
  • 47