How to write binary to file - asp.net

I have code that's supposed to read binary values from the database and convert it into a zip file. It only creates a file that's 43kb big and it can't be extracted. What am I missing?
com = new SqlCommand("SELECT BinFile FROM tbl_reports WHERE DBKey=411", conString);
byte[] blob = (byte[])com.ExecuteScalar();
File.WriteAllBytes("C:\\" + "test.zip", blob);

Use DotNetZip , here is example .
using (ZipFile zip = new ZipFile())
{
zip.Password = pwd;
zip.AddFile(saveFileDialog1.FileName + ".xml");
zip.Save(saveFileDialog1.FileName + ".zip");
}
Additionally , I think you need to convert byte[] to string and then text file .
You can use convert.frombase64string method !
Edit
If you want to write byte[] to file , use this function ,
public bool ByteArrayToFile(string _FileName, byte[] _ByteArray)
{
try
{
System.IO.FileStream _FileStream =
new System.IO.FileStream(_FileName, System.IO.FileMode.Create,
System.IO.FileAccess.Write);
_FileStream.Write(_ByteArray, 0, _ByteArray.Length);
_FileStream.Close();
return true;
}
catch (Exception _Exception)
{
Console.WriteLine("Exception caught in process: {0}",
_Exception.ToString());
}
return false;
}
And call this function likes
com = new SqlCommand("SELECT BinFile FROM tbl_reports WHERE DBKey=411", conString);
byte[] blob = (byte[])com.ExecuteScalar();
ByteArrayToFile("C:\\test.txt",blob);

Related

The most straightforward way to download a file in mvc

I am currently saving an excel file like so on my c drive.
public ActionResult Export()
{
try
{
Excel.Application application = new Excel.Application();
Excel.Workbook workbook = application.Workbooks.Add(System.Reflection.Missing.Value);
Excel.Worksheet worksheet = workbook.ActiveSheet;
var people = db.People.ToList();
worksheet.Cells[1, 1] = "Last Name";
worksheet.Cells[1, 2] = "First Name";
int row = 2;
foreach (var person in people)
{
worksheet.Cells[row, 1] = person.PersonFName;
worksheet.Cells[row, 2] = person.PersonLName;
row++;
}
workbook.SaveAs("c:\\test\\worksheet.xls");
workbook.Close();
Marshal.ReleaseComObject(workbook);
application.Quit();
Marshal.FinalReleaseComObject(application);
ViewBag.Result = "Done";
}
catch(Exception ex)
{
ViewBag.Result = ex.Message;
}
return File("c:\\test\\workseet.xls", "application/vnd.ms-excel", "workseet.xls");
// return View("Success");
}
I can go to c:\\test\workseet.xls and it exists there I can do what ever with it...
I am wanting to transform my method from return a view to return a file download...
I figured that it was as simple as this:
return File("c:\\test\\workseet.xls", "application/vnd.ms-excel", "workseet.xls");
However when I do this method and click the link to download, it gives me this error.
The process cannot access the file 'c:\test\workseet.xls' because it is being used by another process.
This duplicate question is just one of those that show how to use EPPlus to generate Excel files on the server side in a scaleable manner. It's actually a lot easier than using Excel interop and a lot faster. You don't even have to save the file to the disk.
public ActionResult ExportData()
{
//Somehow, load data to a DataTable
using (ExcelPackage package = new ExcelPackage())
{
var ws = package.Workbook.Worksheets.Add("My Sheet");
//true generates headers
ws.Cells["A1"].LoadFromDataTable(dataTable, true);
//Save the workbook to a stream
var stream = new MemoryStream();
package.SaveAs(stream);
string fileName = "myfilename.xlsx";
string contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
stream.Position = 0;
return File(stream, contentType, fileName);
}
}
You can use LoadFromDataTable to fill a sheet from a data table or LoadFromCollection to load data from a collection, eg List<Sale>.
Both methods return an ExcelRange object (a range of cells) that you can use to format individual cells, rows, and columns. You can also create tables from a range and apply themes.
The duplicate goes even farther and shows how you can avoid even the MemoryStream

How do I write in log file from start instead append it to end of file

I have following code for log file
which will create a log file and write log into that file.
But I want to write that log into file in DESC order
so that recent log text will come first.
string FilePath = Path(MYLOG.txt");
if (!File.Exists(FilePath))
{
byte[] fileBytes = null;
fileBytes = Encoding.GetEncoding(1252).GetBytes("My Log -\n");
using (Stream streamToWrite = File.Create(FilePath))
{
streamToWrite.Write(fileBytes, 0, fileBytes.Length);
streamToWrite.Flush();
}
I mean want to write new content from start not to end of the file
I think this will do
string currentContent = String.Empty;
if (File.Exists(filePath))
{
currentContent = File.ReadAllText(filePath);
}
File.WriteAllText(filePath, newContent + currentContent );

File not found exception once deployed to Server

I am using the below code to Upload an Image file to a SharePoint Document Library. The code works fine locally but once deployed to server, i get the Exception as file not found.
String fileToUpload = FlUpldImage.PostedFile.FileName; //#"C:\Users\admin.RSS\Desktop\Photos\me_skype.jpg";
String documentLibraryName = "SiteAssets";
if (!System.IO.File.Exists(fileToUpload))
throw new FileNotFoundException("File not found.", fileToUpload);
SPFolder myLibrary = web.Folders[documentLibraryName];
// Prepare to upload
Boolean replaceExistingFiles = true;
String fileName = CheckStringNull(txtFirstName.Text) + CheckStringNull(txtLastName.Text) + CheckDateNull(txtDOB) + System.IO.Path.GetFileName(fileToUpload); ;
if (fileName.Contains('/'))
{
fileName = fileName.Replace("/", "");
}
if (fileName.Contains(':'))
{
fileName = fileName.Replace(":", "");
}
FileStream fileStream = File.OpenRead(fileToUpload);
//Upload document
SPFile spfile = myLibrary.Files.Add(fileName, fileStream, replaceExistingFiles);
string url = site.ToString() + "/" + spfile.ToString();
if (url.Contains("="))
{
url = url.Split('=')[1];
}
//Commit
myLibrary.Update();
The string fileupload contains URL as C:\Users\admin.RSS\Desktop\Photos\me.jpg This URL is actually the client system and the server side code throws exception as file not found. How to handle this issue?
UPDATE:
I removed the lines of code that checks if the file exists and now i get the exeption on FileStream fileStream = File.OpenRead(fileToUpload); as c:\windows\system32\inetsrv\20120605_133145.jpg cold not be found
Kindly help. Thank You
if (this.fuAvatarUpload.HasFile && this.fuAvatarUpload.PostedFile.FileName.Length > 0)
{
string extension = Path.GetExtension(file.FileName).ToLower();
string mimetype;
switch (extension)
{
case ".png":
case ".jpg":
case ".gif":
mimetype = file.ContentType;
break;
default:
_model.ShowMessage("We only accept .png, .jpg, and .gif!");
return;
}
if (file.ContentLength / 1000 < 1000)
{
Image image = Image.FromStream(file.InputStream);
Bitmap resized = new Bitmap(image, 150, 150);
byte[] byteArr = new byte[file.InputStream.Length];
using (MemoryStream stream = new MemoryStream())
{
resized.Save(stream, System.Drawing.Imaging.ImageFormat.Png);
byteArr = stream.ToArray();
}
file.InputStream.Read(byteArr, 0, byteArr.Length);
profile.ImageUrl = byteArr;
profile.UseGravatar = false;
profileService.UpdateProfile(profile);
this._model.ShowApprovePanel();
}
else
{
_model.ShowMessage("The file you uploaded is larger than the 1mb limit. Please reduce the size of your file and try again.");
}
}
Saving the file physically onto server and than working on the same helped me resolve my issue.

FTP file upload issue - Missing filename

I am trying to upload files via FTP using the following script. The file does upload to the FTP server however the file name is always called Images and has no exstenion.
Its probably something simple i have missed but if anyone know where it is going wrong that would be help.
public static string _FTPusername = "xx";
public static string _FTPPassword = "xxxxx";
public static string _FTPServerAddress = "cp.domainname.co.uk";
public static string _ftpurl = "ftp://cp.domainname.co.uk/Images"; //= "ftp://cp.domainname.co.uk/Images";
try
{
string filename = Path.GetFileName( source );
string ftpfullpath = ConnectionDetails._ftpurl;
FtpWebRequest ftp = (FtpWebRequest)FtpWebRequest.Create( ftpfullpath );
ftp.Credentials = new NetworkCredential( ConnectionDetails._FTPusername, ConnectionDetails._FTPPassword );
ftp.KeepAlive = true;
ftp.UseBinary = true;
ftp.Method = WebRequestMethods.Ftp.UploadFile;
FileStream fs = File.OpenRead( source );
byte[] buffer = new byte[fs.Length];
fs.Read( buffer, 0, buffer.Length );
fs.Close();
Stream ftpstream = ftp.GetRequestStream();
ftpstream.Write( buffer, 0, buffer.Length );
ftpstream.Close();
}
catch( Exception ex )
{
throw ex;
}
The problem would seem to be these 3 lines:
string filename = Path.GetFileName( source );
string ftpfullpath = ConnectionDetails._ftpurl;
FtpWebRequest ftp = (FtpWebRequest)FtpWebRequest.Create( ftpfullpath );
You don't use the filename variable, so the path that gets passed in is
ftp://cp.domainname.co.uk/Images
Try something like this:
string ftpfullpath = ConnectionDetails._ftpurl + "/" + filename;
Found the issue - was a simple school boy error.
public static string _ftpurl = "cp.domainname.co.uk/Images
Should have been:
public static string _ftpurl = "cp.domainname.co.uk

Saving/Loading Images from/to stream instead of a disk

I have the following code which takes an improperly saved Image from the database converts it to a Jpeg and returns the Image in a byte array;
public Byte[] GetImageFromDB(int id)
{
var imageData = _repository.GetImage(id);
var newImageData = ConvertCorruptedImage(imageData, id);
return newImageData;
}
private byte[] ConvertCorruptedImage(byte[] imageData, int id)
{
// Save DB Image as a file.
MemoryStream img = new MemoryStream(imageData);
var saveDBImage = Image.FromStream(img);
string originalFileName = #"c:\original_" + id.ToString() + ".jpg";
string newFileName = #"C:\new" + id.ToString() + ".jpg";
// Delete if already Exists
DeleteImageFile(originalFileName);
saveDBImage.Save(originalFileName);
// Read Saved DB Image From Saved File & Save as jpeg
Bitmap bm = new Bitmap(originalFileName);
bm.Save(newFileName , ImageFormat.Jpeg);
// Return Converted JPEG Image
var newImage = ImageToByte(Image.FromFile(newFileName));
//DeleteCreatedImage(newFileName);
//DeleteCreatedImage(originalFileName);
return newImage;
}
private byte[] ImageToByte(Image img)
{
ImageConverter converter = new ImageConverter();
return (byte[])converter.ConvertTo(img, typeof(byte[]));
}
public static void DeleteImageFile(string fileName)
{
FileInfo file = new FileInfo(fileName);
if (file.Exists && !file.IsReadOnly)
{
System.IO.File.Delete(fileName);
}
}
I was wondering if there was a way to do this without saving a file to the hard disk or if i do save it then deleting it once i am done with it.
I've tried adding a delete for each images (check the commented out portion of the ConvertCorruptedImage method) but i keep getting the following error:
The process cannot access the file 'C:\new_xx.jpg' because it is being used by another process.
I really don't want to be saving images to a hard disk.
Thanks in advance
something along the lines of
var image = Image.FromStream(new MemoryStream(imageData));
Bitmap bmp = new Bitmap(image);
MemoryStream outStream = new MemoryStream();
bmp.Save(outStream,ImageFormat.Jpeg);
return outStream.ToArray();
Use the overload of Bitmap.Save that writes to a Stream.
var stream = new MemoryStream();
bm.Save(stream, ImageFormat.Jpeg);
You can load the bitmap directly from your MemoryStream:
Bitmap bm = new Bitmap(imgStream);
You can also save the bitmap to a stream:
MemoryStream newImgStream = new MemoryStream();
bm.Save(newMemoryStream, ImageFormat.Jpeg);

Resources