That code is similar to what I've used before with the following differences, however:
1. In place of Response.Clear(), I use the following (but seem to recall that Clear() clears both Content and Headers anyway):
Response.ClearContent();
Response.ClearHeaders();
2. I thought that when specifying the filename for the Content-Disposition header, the filename needed to be enclosed in single quotes:
Response.AppendHeader("Content-Disposition", "attachment; filename=\"" + file.Name + "\"");
3. Before calling Response.End, I explicitly flush the content to the stream:
Response.Flush();
Response.End();
I would also recommend that for security reasons alone you should instead use the DNN core LinkClick.aspx handler for file download. You should call the following method (or one of it's overloads) to construct the download link:
Public Function LinkClick(ByVal Link As String, ByVal TabID As Integer, ByVal ModuleID As Integer, ByVal TrackClicks As Boolean, ByVal ForceDownload As Boolean) As String
Link may be either a reference to a DNN FileId in the form of "fileid=####" or a filepath. The ForceDownload parameter should be true to force the file open/save dialog box to appear.