I am having trouble uploading files(.mp3) stored in the local folder by user to firebase.
This is how a file is retrieved from local folder:
StorageFolder folder = ApplicationData.Current.LocalFolder;
var songfolder = await folder.GetFolderAsync("Songs");
StorageFile mp3file = await songfolder.GetFileAsync(mp3fileforupload);
And this is how I create a stream file of the file and upload:
var stream = File.Open(mp3file.Path, FileMode.Open);
var task = new FirebaseStorage("-my-bucket-.appspot.com")
.Child("songs")
.Child(new_song_id)
.PutAsync(stream);
task.Progress.ProgressChanged += (s, f) => uploadProgress(f.Percentage);
var downloadurl = await task;
Debug.WriteLine("DOWNLOAD_URL " + downloadurl);
The file fails to upload. From the Step-up-labs documentation, the file should be uploaded as a stream of a file. This worked when uploading files from the Assets folder, but does not work with files from local folder. I have tried uploading from the MostRecentlyUsedList but it still fails to upload. Any idea why this is failing?
Try this instead to open the file
Windows.Storage.StorageFolder storageFolder =
Windows.Storage.ApplicationData.Current.LocalFolder;
Windows.Storage.StorageFile sampleFile =
await storageFolder.GetFileAsync(mp3file.Path);
var stream = await sampleFile.OpenAsync(Windows.Storage.FileAccessMode.ReadWrite);
The Step-Up-Labs C# Firebase-Storage API uses Stream for file uploads. Files should be uploaded as a Stream. What has worked for me is using a Memory Stream.
First I retrieved the file from local folder:
StorageFolder folder = ApplicationData.Current.LocalFolder;
var songfolder = await folder.GetFolderAsync("Songs");
StorageFile mp3file = await songfolder.GetFileAsync(mp3fileforupload);
Then I read the bytes of the file using a DataReader:
byte[] fileBytes = null;
using (IRandomAccessStreamWithContentType stream = await mp3file.OpenReadAsync())
{
fileBytes = new byte[stream.Size];
using (DataReader reader = new DataReader(stream))
{
await reader.LoadAsync((uint)stream.Size);
reader.ReadBytes(fileBytes);
}
}
Then I used a MemoryStream for the upload:
Stream stream = new MemoryStream(fileBytes);
var task = new FirebaseStorage("-my-bucket-.appspot.com")
.Child("songs")
.Child(new_song_id)
.PutAsync(stream);
task.Progress.ProgressChanged += (s, f) => uploadProgress(f.Percentage);
var downloadurl = await task;
That did the trick. The file uploaded.
Related
Use the OneDrive SDK to upload files.
At this time, you have to pass the file path, but uploading using the code takes a long time.
Can I upload files even if I pass the temporary file path?
Currently I get the file path after saving the file to the server.
In this case, an issue arises from speed problems.
Is there any way to look at the temporary file path?
public async Task<JObject> UploadLargeFiles(string upn, IFormFile files)
{
var jObject = new JObject();
int fileSize = Convert.ToInt32(files.Length);
var folderName = Path.Combine("wwwroot", "saveLargeFiles");
var pathToSave = Path.Combine(System.IO.Directory.GetCurrentDirectory(), folderName);
var fullPath = "";
if (files.Length > 0)
{
var fileName = files.FileName;
fullPath = Path.Combine(pathToSave, fileName);
using (var stream = new FileStream(fullPath, FileMode.Create))
files.CopyTo(stream);
}
var filePath = fullPath;
var fileStream = System.IO.File.OpenRead(filePath);
GraphServiceClient client = await MicrosoftGraphClient.GetGraphServiceClient();
var uploadProps = new DriveItemUploadableProperties
{
ODataType = null,
AdditionalData = new Dictionary<string, object>
{
{ "#microsoft.graph.conflictBehavior", "rename" }
}
};
var item = this.SelectUploadFolderID(upn).Result;
var uploadSession = await client.Users[upn].Drive.Items[item].ItemWithPath(files.FileName).CreateUploadSession(uploadProps).Request().PostAsync();
int maxChunkSize = 320 * 1024;
var uploadTask = new LargeFileUploadTask<DriveItem>(uploadSession, fileStream, maxChunkSize);
var response = await uploadTask.UploadAsync();
if (response.UploadSucceeded)
{
return
}
else
{
return null;
}
}
Your server's disk is probably not what makes this slow. By default, uploaded files are stored in a temporary directory, which you can save permanently by using CopyTo(FileStream) like you do.
You can skip this step and call IFormFile.OpenReadStream() to obtain a stream to the temporary file, then pass that to the LargeFileUploadTask.
Point is, it's probably the uploading to OneDrive that takes the largest amount of time. Depending on your setup, you may want to save files into a queue directory (the temp file gets deleted after the request completes), and have a background service read that queue and upload them to OneDrive.
I am writing text to a file in Windows Phone 8.1 like this:
private static async Task WriteData(String fileName, String content)
{
Byte[] data = Encoding.Unicode.GetBytes(content);
var folder = ApplicationData.Current.LocalFolder;
var file = await folder.CreateFileAsync(fileName, CreationCollisionOption.ReplaceExisting);
using (var s = await file.OpenStreamForWriteAsync())
{
await s.WriteAsync(data, 0, data.Length);
}
}
But when I read the file, it comes back empty. I have verified that there isn't some other method overwriting it by reading from the file immediately after I write to it. Am I missing something obvious here?
Maybe you can try:
public async Task SaveStreamToFile(Stream streamToSave, string fileName, CancellationToken cancelToken)
{
Byte[] buf= Encoding.Unicode.GetBytes(content);
var folder = ApplicationData.Current.LocalFolder;
StorageFile file = await folder.CreateFileAsync(fileName, CreationCollisionOption.ReplaceExisting);
using (Stream fileStram = await file.OpenStreamForWriteAsync())
{
int bytesread = 0;
while ((bytesread = await streamToSave.ReadAsync(buf, 0, BUFFER_SIZE)) > 0)
{
await fileStram.WriteAsync(buf, 0, bytesread);
cancelToken.ThrowIfCancellationRequested();
}
}
}
I was having the same problem. I save 2 files, one with debug information, and one with application specific information (a list of routes).The debug information seems to work OK
StorageFolder local = ApplicationData.Current.LocalFolder;
var file = await local.CreateFileAsync "debug.txt",CreationCollisionOption.ReplaceExisting);
await FileIO.WriteTextAsync(file, sbDebugInformation.ToString());
but the CreateCollisionOption.ReplaceExisting seemed to be causing problems with the other information, and I ended up with this, after many alternate attempts
StorageFolder local = ApplicationData.Current.LocalFolder;
var json = new DataContractJsonSerializer(typeof(RouteList));
var file = await local.CreateFileAsync(filename,CreationCollisionOption.OpenIfExists);
MemoryStream stream = new MemoryStream();
json.WriteObject(stream, routes);
await FileIO.WriteBytesAsync(file, stream.ToArray());
I'm doing a backup of my app database to OneDrive. The database records refer to images that are stored in isolated storage. I backup those images too. The database files.
The destinations of the backup file is:
me/skydrive/my_documents/MyCompany/MyApp/MyBackup.bak
The destination of the jpg image files is
me/skydrive/my_documents/MyCompany/MyApp/MyBackup Images/*.jpg
The database restores fine, but the images don't. I've verified that the image is backed up properly on SkyDrive - I can see it and open it fine from SkyDrive. However, when I restore, the file is corrupt. Here's the code I use to restore:
dynamic cmpFolder = await oneDrive.FindFolder("MyCompany", "me/skydrive/my_documents");
dynamic appFolder = await oneDrive.FindFolder(AppName, cmpFolder.id);
string imagesFileName = Path.GetFileNameWithoutExtension(selectedFile.FileName) + " Images";
dynamic imgFolder = await oneDrive.FindFolder(imagesFileName, appFolder.id);
dynamic fileList = await oneDrive.FindFiles(imgFolder.id);
foreach (var fileData in fileList.data)
{
string fileName = fileData.name;
var file =
await wilFolder.CreateFileAsync(
Path.GetFileName(fileName), CreationCollisionOption.ReplaceExisting);
var result = await client.BackgroundDownloadAsync(selectedFile.FileID +
"/content/", new Uri(#"\shared\transfers\" + fileName, UriKind.Relative));
}
Using ISETool and viewing \shared\transfers, I can see that the file is no longer readable. It's size is about 128k, whereas the original image was much larger.
I've also tried this, which was my original code until I began seeing the problem:
var downloadResult = await client.DownloadAsync(selectedFile.FileID + "/content/");
using (Stream oneDriveStream = downloadResult.Stream)
{
oneDriveStream.Position = 0;
byte[] imageBytes = new byte[oneDriveStream.Length];
int count = oneDriveStream.Read(imageBytes, 0, imageBytes.Length);
using (var s = await file.OpenStreamForWriteAsync())
{
oneDriveStream.CopyTo(s);
// and tried this
//s.Write(imageBytes, 0, imageBytes.Length);
}
}
For reference, here's the FindFolder and FindFiles implementations:
public async Task<dynamic> FindFiles(string folderName)
{
LiveOperationResult filesResult = await client.GetAsync(folderName + "/files");
dynamic files = filesResult.Result;
return files;
}
public async Task<dynamic> FindFolder(string folderName, string parentFolder)
{
LiveOperationResult folderResult = await client.GetAsync(parentFolder + "/files?filter=folders");
dynamic folders = folderResult.Result;
foreach (var folder in folders.data)
if (folder.name == folderName)
return folder;
return null;
}
How do I successfully download *.jpg images from my OneDrive folder?
Try this for your download path instead:
var downloadResult = await client.DownloadAsync(selectedFile.FileID + "/picture?type=full");
I'm trying to launch pdf reader with the code below but it does not work. Can somebody help me?
private async Task<StorageFile> WriteData(string fileName, byte[] data)
{
StorageFolder folder = ApplicationData.Current.LocalFolder;
StorageFile file = await folder.CreateFileAsync(fileName, CreationCollisionOption.ReplaceExisting);
using (Stream s = await file.OpenStreamForWriteAsync())
{
await s.WriteAsync(data, 0, data.Length);
s.Close();
}
return file;
}
private async Task<bool> OpenPdf(StorageFile file)
{
var uri = new Uri(file.Path, UriKind.RelativeOrAbsolute);
bool result = await Windows.System.Launcher.LaunchUriAsync(uri);
return result;
}
private async void FetchPdf() {
// Fetch pdf bytes to network
//....
StorageFile file = await WriteData("test.pdf", data);
if (file != null) {
bool result = await OpenPdf(file);
if (result)
Debug.WriteLine("Success");
else
Debug.WriteLine("Cannot open pdf file.");
}
}
result is always false and so launcher is not presented.
I used LaunchUriAsync because LaunchFileAsync is not implemented on Windows Phone.
LaunchUriAsync isn't supported on Windows Phone 8 per the documentation. It throws an exception if called
You can use Windows.System.Launcher.LaunchFileAsync to launch a StorageFile.
This code works for example (assming there's a file called "metro.pdf" in the project, with the Build Action set to Content, with Copy to Output Directory set to Copy if Newer).
var installedLocation = Windows.ApplicationModel.Package.Current.InstalledLocation;
var assets = await installedLocation.GetFolderAsync("Assets");
var pdf = await assets.GetFileAsync("metro.pdf");
Windows.System.Launcher.LaunchFileAsync(pdf);
Called the API and saved the byte array to file
public static async void WriteDataToIsolatedStorageFile(string fileName, byte[] data)
{
using (IsolatedStorageFile storageFile = IsolatedStorageFile.GetUserStoreForApplication())
{
using (IsolatedStorageFileStream stream = storageFile.OpenFile(fileName, FileMode.Create))
{
if ((data != null) && (data.Length > 0))
{
await stream.WriteAsync(data, 0, data.Length);
}
}
}
}
opened the file in pdf reader using
private async void StartExternalPDFApp()
{
StorageFolder localFolder = await FileManager.FindDirectory(FileManager.RelativeStorageDirectoryLocalStorage);
StorageFile storageFile = await localFolder.GetFileAsync(PdfFileName);
await Windows.System.Launcher.LaunchFileAsync(storageFile);
}
localFolder is Windows.Storage.ApplicationData.Current.LocalFolder
just put the anyFile.pdf in Assets folder, and make its build action to Content, and then Just make the function Async ... and then Put "await" before Windows.System.Launcher.LaunchFileAsync(pdf);
it worked fine for me. Nice.
See this.
private async void privacyPolicy_Click(object sender, EventArgs e)
{
var installedLocation = Windows.ApplicationModel.Package.Current.InstalledLocation;
var assets = await installedLocation.GetFolderAsync("Assets");
var pdf = await assets.GetFileAsync("PrivacyPolicy.pdf");
await Windows.System.Launcher.LaunchFileAsync(pdf);
}
I'm creating a windows rt application which contains more than 1000 .txt files from which I'm getting their contents.
These text files are part of my project but I can't read them with code.
This is my code
static async Task ReadFile(string filePath, List<string> list)
{
try
{
StorageFile file = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///" + filePath));
var readThis = await FileIO.ReadLinesAsync(file);
foreach (var line in readThis)
{
list.Add(line);
}
}
catch (FileNotFoundException)
{
}
}
where filePath is : "txt/data/14b.txt.
When code is executed Lists are filled with the data but application crashes and I'm sent in this line of app.g.i.cs
if (global::System.Diagnostics.Debugger.IsAttached) global::System.Diagnostics.Debugger.Break();
any ideas ?
Try marking your text files Build Action as Content. Then
var file = await StorageFile.GetFileFromApplicationUriAsync( new Uri( "ms-appx:///" + filePath ) );
Should load a file.
var storageFile = await StorageFile.GetFileFromApplicationUriAsync(new Uri(String.Format("ms-appx:///{Project name}/txt/data/{0}", fileName)));
Try with replacing
StorageFile file = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///" + filePath));
to
var ProjectFolder = Windows.ApplicationModel.Package.Current.InstalledLocation;
StorageFile file = await ProjectFolder.GetFileAsync(fileName);