1

I use Interop to SaveAs(D:/Temp) a template excel sheet after the changes are made. Then I use FileStream to send the user a Pop-up to save this file. But that file in D:\Temp still exists. Is there a way to delete this file on Pop-up response?

//Save the Excel File
SaveExcelFile(exportPath, sourceFile, excelWorkBook,
                excelApllication, excelWorkSheet);

#region Pop Up and File Open
if (System.IO.File.Exists(sourceFile))
{
    FileStream fsSource = 
        new FileStream(sourceFile, FileMode.Open, FileAccess.Read);

    return File(fsSource, "application/vnd.ms-excel", "FileName" + .xls");
}
else
{
    return View();
}
#endregion
Kjartan
  • 18,591
  • 15
  • 71
  • 96
Abhid
  • 266
  • 1
  • 5
  • 18

4 Answers4

4

To delete one file

string filePath)= @"C:\MyDir\filename.txt";
public bool RemoveFile(string filePath)
{
try
{
if (File.Exists(filePath))
{
File.Delete(filePath);
return true;
}
else
return true;
}
catch (Exception ex)
{
return false;
}
}

Delete all files

string[] filePaths = Directory.GetFiles(@"c:\MyDir\");
foreach (string filePath in filePaths)
  File.Delete(filePath);

To delete all files using one code line

Array.ForEach(Directory.GetFiles(@"c:\MyDir\"),
              delegate(string path) { File.Delete(path); });
prabhakaran S
  • 718
  • 1
  • 6
  • 13
2

You can use File.Delete method.

if (File.Exists("File_Path"))
{
 File.Delete("File_Path");
}

Updated

For downloading binary files,

using (FileStream fs = File.OpenRead(path))
{
    int length = (int)fs.Length;
    byte[] buffer;

    using (BinaryReader br = new BinaryReader(fs))
    {
        buffer = br.ReadBytes(length);
    }

    Response.Clear();
    Response.Buffer = true;
    Response.AddHeader("content-disposition", String.Format("attachment;filename={0}", Path.GetFileName(path)));
    Response.ContentType = "application/" + Path.GetExtension(path).Substring(1);
    Response.BinaryWrite(buffer);
    Response.Flush();
    Response.End();
}

Found this code from here

Community
  • 1
  • 1
Bharadwaj
  • 2,535
  • 1
  • 22
  • 35
  • I dont't think file stream will allow the file to be deleted when in use. – Abhid Mar 06 '14 at 12:15
  • CONFIRMATION: Application errors out if `File.Delete();` is placed before return statement. – Abhid Mar 06 '14 at 12:22
  • What next will happen after returning? I mean code flow – Bharadwaj Mar 06 '14 at 12:26
  • Is `Response.WriteFile(filepath);` in your option to provide user to download file? – Bharadwaj Mar 06 '14 at 12:30
  • The return statement gives me a Pop Up to save the file. That is the end of flow for this functionality. – Abhid Mar 06 '14 at 12:30
  • No, the return statement does that for me. – Abhid Mar 06 '14 at 12:32
  • If you use `Response.WriteFile` and `Responce.Flush` in sequence then you can all `File.Delete` immediatly. Because it is fully synchronous as explained in http://stackoverflow.com/questions/200901/when-can-i-delete-a-file-after-using-it-in-response-writefile – Bharadwaj Mar 06 '14 at 12:38
  • `Response.WriteFile` gave me some weird output. :/ Maybe I'm using it wrong. – Abhid Mar 06 '14 at 12:53
1

Instead of creating a temp file, loading it to stream, and then trying to delete it, I suggest that you create the file directly in memory stream (i.e. System.IO.MemoryStream) in the first place, so you don't have to load it and delete it.

If you cannot create it directly in memory stream, the main issue is that you cannot delete the temp file while you're using it in the FileStream. In this case, you copy the FileStream to a MemoryStream, close and dispose the FileStream, delete the temp file, and then return the MemoryStream to the user.

You can use the function bellow to copy streams correctly.

// Author: Racil Hilan.
/// <summary>Copies data from a source stream to a target stream.</summary>
private static void CopyStream(Stream SourceStream, Stream TargetStream) {
  const int BUFFER_SIZE = 4096;
  byte[] buffer = new byte[BUFFER_SIZE];
  //Reset the source stream in order to process all data.
  if (SourceStream.CanSeek)
    SourceStream.Position = 0;
  //Copy data from the source stream to the target stream.
  int BytesRead = 0;
  while ((BytesRead = SourceStream.Read(buffer, 0, BUFFER_SIZE)) > 0)
    TargetStream.Write(buffer, 0, BytesRead);
  //Reset the source stream and the target stream to make them ready for any other operation.
  if (SourceStream.CanSeek)
    SourceStream.Position = 0;
  if (TargetStream.CanSeek)
    TargetStream.Position = 0;
}
Racil Hilan
  • 24,690
  • 13
  • 50
  • 55
  • I kind of need the SaveAs of Interop to do what I need to do. Can I do a SaveAs into MemoryStream? – Abhid Mar 06 '14 at 12:19
  • I don't know, you have to check if it has an overload that takes a stream instead of a file. Or maybe it has another method that does. If so, then yes you can save into MemoryStream. If not, I've just edited my answer. You can copy your FileStream to MemoryStream. – Racil Hilan Mar 06 '14 at 12:25
  • EDIT: This worked beautifully! But the file saved doesn't have the correct data. :( – Abhid Mar 06 '14 at 12:41
  • OK, it is very easy to make little mistakes when dealing with streams. Don't get frustrated. What exactly do you get? Make sure you're using the correct encoding, and you're copying the stream correctly. I have a little function in my library to copy streams. I will add it to my answer in a moment. – Racil Hilan Mar 06 '14 at 12:52
  • I just do a `FsSource.CopyTo(MsSource);` and use MsSource in my return statement. – Abhid Mar 06 '14 at 13:16
  • THANKS A lot. The method works , and the file is generated perfectly. Thanks again. :) – Abhid Mar 06 '14 at 13:23
  • Just a query: Why do you give BUFFER_SIZE as 4096? – Abhid Mar 06 '14 at 13:28
  • 1
    UPDATE: I read your method and improvised and did something like this: `fsSource.CopyTo(MsSource); if (MsSource.CanSeek) { MsSource.Position = 0; }` and it works! – Abhid Mar 06 '14 at 13:38
  • 1
    Yeah, as I mentioned, when dealing with streams it's easy to make small mistakes. Returning the source stream to the start position is important for the code after the copy. As for your question about the buffer type, you can use any value. The default value 4096 means 4 KB chunks and is probably a good balance between memory usage and performance in most scenarios, but in some cases another value can be better. See the docs http://msdn.microsoft.com/en-us/library/dd783870(v=vs.110).aspx – Racil Hilan Mar 06 '14 at 13:48
  • In the docs I mentioned above, see under [Remarks: Copying begins at the current position in the current stream, and does not reset the position of the destination stream after the copy operation is complete.]. It does not mention why it does not reset it. Perhaps for performance, so you only reset it when you need that. They should've mentioned the reason. Go figure. – Racil Hilan Mar 06 '14 at 13:52
0

You can use File.Delete() for this. Just make sure you've closed the stream before you try to delete the file, and preferably, that you have been able to send whatever you need to.

I'm guessing you don't want to delete the file if the main operation fails.

Kjartan
  • 18,591
  • 15
  • 71
  • 96