I'm trying to upload files in azure.
So basically I'm trying to convert the file in a stream so I can create a file on server and write its data.
public async Task UploadFileOnAzure( string path, string name, IFormFile file)
{
//create directory
await _dlsService.CreateDir(path, name);
//create file
var f = file.FileName;
var ext = Path.GetExtension(f);
string filepath = $"{path}/{name.ToString()}/{f}";
try
{
using (var ms = new MemoryStream())
{
using (var fileStram = file.OpenReadStream())
{//sometimes it breakes right before this line, other times it doesn't write the file(excel)
fileStram.CopyTo(ms);
using (Stream str = await _dlsService.CreateFile(filepath)) //file is created as empty ofcourse
{
ms.CopyTo(str);
str.Close();
//this doesnt write on the file
}
}
}
}
catch(Exception ex)
{
Console.WriteLine(ex.Message.ToString());
}
}
Cannot access a disposed object. Object name: FileBufferingReadStream. I get this error quite often. Can't seem to understand why.
I would like to just write on the created file. Pls help :)
Related
I am trying to read a csv file from my azure storage account.
To convert each line into an object and build a list of those objects.
It keeps erring, and the reason is it cant find the file (Blob not found). The file is there, It is a csv file.
Error:
StorageException: The specified blob does not exist.
BatlGroup.Site.Services.AzureStorageService.AzureFileMethods.ReadCsvFileFromBlobAsync(CloudBlobContainer container, string fileName) in AzureFileMethods.cs
+
await blob.DownloadToStreamAsync(memoryStream);
public async Task<Stream> ReadCsvFileFromBlobAsync(CloudBlobContainer container, string fileName)
{
// Retrieve reference to a blob (fileName)
var blob = container.GetBlockBlobReference(fileName);
using (var memoryStream = new MemoryStream())
{
//downloads blob's content to a stream
await blob.DownloadToStreamAsync(memoryStream);
return memoryStream;
}
}
I've made sure the file is public. I can download any text file that is stored there, but none of the csv files.
I am also not sure what format to take it in as I need to iterate through the lines.
I see examples of bringing the whole file down to a temp drive and working with it there but that seems unproductive as then I could just store the file in wwroot folder instead of azure.
What is the most appropriate way to read a csv file from azure storage.
Regarding how to iterate through the lines, after you get the memory stream, you can use StreamReader to read them line by line.
Sample code as below:
using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Blob;
using System;
using System.IO;
namespace ConsoleApp17
{
class Program
{
static void Main(string[] args)
{
string connstr = "your connection string";
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(connstr);
CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
CloudBlobContainer container = blobClient.GetContainerReference("t11");
CloudBlockBlob blockBlob = container.GetBlockBlobReference("students.csv");
string text="";
string temp = "";
using (var memoryStream = new MemoryStream())
{
blockBlob.DownloadToStream(memoryStream);
//remember set the position to 0
memoryStream.Position = 0;
using (var reader = new StreamReader(memoryStream))
{
//read the csv file as per line.
while (!reader.EndOfStream && !string.IsNullOrEmpty(temp=reader.ReadLine()))
{
text = text + "***" + temp;
}
}
}
Console.WriteLine(text);
Console.WriteLine("-------");
Console.ReadLine();
}
}
}
My csv file:
The test result:
public static async Task Store(ObservableCollection<Product> list)
{
Uri path = new Uri("ms-appx:///ListCollection.json");
var store = await StorageFile.GetFileFromApplicationUriAsync(path);
var stream = File.OpenWrite(store.Path);
var serialize = new DataContractJsonSerializer(typeof(ObservableCollection<Product>));
serialize.WriteObject(stream, list);
}
Ok this is the piece of code that I used to serialize a collection , works very well , no problem with it , but what I want and tried and no success. I created a JSON file in my project. I want to store and stream data to that file. I tried some methods but no success , how do I open a stream to a file that is currently in my project?
EDITED : Commented the code that was working and wrote what I intend to do. Thanks for support.
When I get to this line
var stream = File.OpenWrite(store.Path); it says that is inaccesible.
What I intend to do is serialize some data to a file called ListCollection.json that is emtpy , that file is project file. It might be the stream or it might be the file that gives me that error. No idea.
My guess is that your project file is located in the installation directory of your application and as far as I know you can't just write to that directory.
You would have to put a deployment action in your solution that writes the desired project file to the application data directory. There you should be able to write it.
I looked through some of the documentation and came accross this:
MSDN
The app's install directory is a read-only location.
I found a Link which makes use of a little hack or so it seems.
I am not sure if this will work if the application is deployed etc.
but you can try this to write the file.
I am not sure if you need a stream or not but feel free to comment:
private void Button_Click(object sender, RoutedEventArgs e)
{
ObservableCollection<string> list = new ObservableCollection<string>();
list.Add("Hallo");
list.Add("Welt");
Task t = Store(list);
}
public static async Task Store(ObservableCollection<string> list)
{
StorageFile file = await GetStorageFileFromApplicationUriAsync();
if (file == null)
{
file = await GetStorageFileFromFileAsync();
}
if (file != null)
{
await file.DeleteAsync();
await CreateFileInInstallationLocation(list);
}
}
private static async Task<StorageFile> GetStorageFileFromFileAsync()
{
StorageFile file = null;
if (file == null)
{
try
{
StorageFolder folder = Windows.ApplicationModel.Package.Current.InstalledLocation;
file = await folder.GetFileAsync("ListCollection.json");
}
catch
{ }
}
return file;
}
private static async Task<StorageFile> GetStorageFileFromApplicationUriAsync()
{
StorageFile file = null;
try
{
Uri path = new Uri("ms-appx:///ListCollection.json");
file = await StorageFile.GetFileFromApplicationUriAsync(path);
}
catch
{ }
return file;
}
private static async Task CreateFileInInstallationLocation(ObservableCollection<string> list)
{
var pkg = Windows.ApplicationModel.Package.Current;
var installedLocationFolder = pkg.InstalledLocation;
try
{
var file = await installedLocationFolder.CreateFileAsync("ListCollection.json", Windows.Storage.CreationCollisionOption.GenerateUniqueName);
var filePath = file.Path;
DataContractJsonSerializer serialize = new DataContractJsonSerializer(typeof(ObservableCollection<String>));
using (Stream stream = await file.OpenStreamForWriteAsync())
{
serialize.WriteObject(stream, list);
stream.Flush();
}
}
catch (Exception ex)
{
var msg = ex.Message;
}
}
What this basically does is:
Find the file
Delete the file
Create a new file
Write your JSON to the file
I am really not an expert on this matter and it even to me seems pretty hacky but it apparently does the job.
If you can avoid writing to the install directory do it and use the method Frank J proposed
I try to create a text file and write some data to it. I am using the following code:
public void AddNews(string path,string News_Title,string New_Desc)
{
FileStream fs = null;
string fileloc = path + News_Title+".txt";
if (!File.Exists(fileloc))
{
using (fs = new FileStream(fileloc,FileMode.OpenOrCreate,FileAccess.Write))
{
using (StreamWriter sw = new StreamWriter(fileloc))
{
sw.Write(New_Desc);
}
}
}
}
I got this exception in stream writer:
The process cannot access the file '..............\Pro\Content\News\AllNews\Par.txt'
because it is being used by another process.
Text file is created, but I can't write to it.
When you create your StreamWriter object, you're specifying the same file that you already opened as a FileStream.
Use the constructor overload of StreamWriter that accepts your FileStream object, instead of specifying the file again, like this:
using (StreamWriter sw = new StreamWriter(fs))
I would simply do this:
public void AddNews(string path, string News_Title, string New_Desc)
{
string fileloc = Path.Combine(path, News_Title+".txt");
if (!File.Exists(fileloc)) {
File.WriteAllText(fileloc, New_Desc);
}
}
Note that I use Path.Combine as a better way to create paths, and File.WriteAllText as a simple way of creating a file and writing something to it. As MSDN says:
If the target file already exists, it is overwritten.
so we first check if the file already exists, as you did. If you want to overwrite its contents, just don't check and write directly.
The issue could be that the file is open or in use. Consider checking if the file is open before writing to it...
public bool IsFileOpen(FileInfo file)
{
FileStream stream = null;
try
{
stream = file.Open(FileMode.Open, FileAccess.ReadWrite, FileShare.None);
}
catch (IOException)
{
// Is Open
return true;
}
finally
{
if (stream != null)
stream.Close();
}
//Not Open
return false;
}
Good Luck!
using (TextWriter tw = new StreamWriter(path, true))
{
tw.WriteLine("The next line!");
}
I have been trying to get the durationstring of a piece of video content that has been uploaded to an MVC4 application using the MediaInfo.dll which I have added to the application as a reference.
I am successfully able to view the details of the file when typing the location of my file locally using the following code:
MediaFile uploadedFile = new MediaFile("C:\\Users\\jp\\Desktop\\Quarry.mp4");
string duration = uploadedFile.General.DurationString.ToString();
However when I try to use this on an uploaded file I am not getting back the information that I had expected. My controller is as follows:
[HttpPost, ValidateInput(true)]
public ActionResult NewContent(HttpPostedFileBase postedFile, string username, FormCollection form)
{
if (postedFile != null)
{
HttpPostedFileBase postedFileCopy = postedFile;
postedFileCopy.InputStream.Position = 0;
Stream stream = postedFile.InputStream;
MediaFile uploadedFile = new MediaFile(Server.MapPath(postedFile.FileName));
string duration = uploadedFile2.General.DurationString.ToString();
string[] name = form.GetValues("name");
string[] author = form.GetValues("author");
string[] description = form.GetValues("description");
TimeSpan videoDuration = TimeSpan.Parse(duration);
try
{
avm.AddContent(postedFile, stream, Convert.ToString(name[0]), Convert.ToString(author[0]), Convert.ToString(description[0]), videoDuration);
return RedirectToAction("Contents", "Admin");
}
catch (Exception ex)
{
System.Diagnostics.EventLog.WriteEntry("Application", ex.Message, System.Diagnostics.EventLogEntryType.Error);
return RedirectToAction("Unsuccessful", "Admin");
}
}
else
return RedirectToAction("NewCourse", "Admin");
}
I have tried:
MediaFile uploadedFile = new MediaFile(Server.MapPath(postedFile.FileName));
MediaFile uploadedFile = new MediaFile(postedFile.FileName);
MediaFile uploadedFile = new MediaFile(postedFile.toString());
MediaFile uploadedFile = new MediaFile(System.IO.Path.GetFullPath(postedFile.FileName);
Any ideas of how I can get MediaInfo to recognise the postedFile in the same manner it is able to read the local file. Or how I can retrieve the path of the client machine's file location.
There is a way you can parse a file using a stream instead of a file.
Look into these methods:
Open_Buffer_Init(..)
Open_Buffer_Continue(..)
Open_Buffer_Continue_GoTo_Get(..)
Open_Buffer_Init(..)
It took me a while to work out how to get the IntPtr for the buffer.. remember to use GCHandle and AddrOfPinnedObject
My sample is all over the place if you need any more help I'll try to get my code working again.
I am working on a project and I need to upload a CSV file and read it.
I am working in Visual Studio 2010 and MVC3 and C# language.
If I am to use html fileuplaod control, how I am suppose to take the uploaded file and read it in the client side itself without saving the file in the server.
Do I have to use the jquery?
I have searched but did not get solution to meet my requirements. I am new to MVC3 and CSV file handling and quite confused.
*What is the easiest way to upload a .csv file and read it in order to save it in the database.
A clear solution would be highly appreciated.Thanks.
What you can do is save the file on server, then after you read the content from them you can delete the file.
I think there is a no way you can read the from client side. You must upload it on ur server to read that.
using (StreamReader CsvReader = new StreamReader(input_file))
{
string inputLine = "";
while ((inputLine = CsvReader.ReadLine()) != null)
{
values.Add(inputLine.Trim().Replace(",", "").Replace(" ", ""));
}
CsvReader.Close();
return values;
}
You should be able to access the data without saving it - using the InputStream property
http://msdn.microsoft.com/en-us/library/system.web.httppostedfile.inputstream.aspx
and this (see Paulius Zaliaduonis answer)
private async Task<string> ProcessAsync(string surveyId)
{ if(!Request.Content.IsMimeMultipartContent())
{
return "|UnsupportedMediaType";
}
try
{
var provider = new MultipartMemoryStreamProvider();
await Request.Content.LoadIntoBufferAsync().ConfigureAwait(false);
await Request.Content.ReadAsMultipartAsync(provider).ConfigureAwait(false);
HttpContent content = provider.Contents.FirstOrDefault();
if(content != null)
{
Stream stream = await content.ReadAsStreamAsync().ConfigureAwait(false);
using (StreamReader CsvReader = new StreamReader(stream))
{
string inputLine = "";
while ((inputLine = CsvReader.ReadLine()) != null)
{
string[] vars = inputLine.Split(',');
}
CsvReader.Close();
//return values;
}
}
}
catch(Exception e)
{
return e.ToString();
}
return "Nothing To Process";
}