Uploading multiple files to firbase storage | Unity - c#

Hey I'm trying to upload all files located in a folder to firestore storage.
However im quite new to c# and unity.
I have the following code to upload a file located in the folder.
if(Permission.HasUserAuthorizedPermission(Permission.ExternalStorageRead)){
Debug.Log("Permissions Found");
var Directory_path = ("SparseSpatialMap/Copia.meta");
var path = (Application.persistentDataPath + "/" + Directory_path);
//Firestore Reference
storage = FirebaseStorage.DefaultInstance;
storageReference = storage.GetReferenceFromUrl("gs://houdini-ac884.appspot.com");
StreamReader stream = new StreamReader(path);
// Create a reference to the file you want to upload
StorageReference riversRef = storageReference.Child("uploads/newFile.meta");
// Upload the file to the path "uploads/newFile.meta"
riversRef.PutStreamAsync(stream.BaseStream)
.ContinueWith((task) => {
if (task.IsFaulted || task.IsCanceled) {
Debug.Log(task.Exception.ToString());
// Uh-oh, an error occurred!
}
else {
// Metadata contains file metadata such as size, content-type, and download URL.
StorageMetadata metadata = task.Result;
string md5Hash = metadata.Md5Hash;
Debug.Log("Finished uploading...");
Debug.Log("md5 hash = " + md5Hash);
}
});
} else {
Debug.Log("No Permissions");
Permission.RequestUserPermission(Permission.ExternalStorageRead);
return;
}
The file i uploaded with success is located here " /storage/emulated/0/Android/data/estg.easy.ar/files/SparseSpatialMap/Copia.meta "
I want to upload all files in the /SparseSpatialMap direcory

What you’re looking for is a way to get all file names, or paths. Try importing System.IO if you have already then you can use Directory.GetFiles(path) replacing path with the folder directory. Then you should have an array of strings representing each file.

For anyone looking for the solution this was how i did it.
got all files via their folder with DirectoryInfo and uploaded each individually using it's the respective name
if (Permission.HasUserAuthorizedPermission(Permission.ExternalStorageRead)){ //Cria ficheiros em branco (Ou por nao ter acesso a um ficheiro que está a ser usado ou por ser Asyncrono)
Debug.Log("Permissions Found");
DirectoryInfo d = new DirectoryInfo(Application.persistentDataPath + "/SparseSpatialMap");
FileInfo[] Files = d.GetFiles("*.meta"); //Getting meta files
string str = "";
foreach(FileInfo file in Files )
{
str = str + ", " + file.Name;
var Directory_path = ("SparseSpatialMap/" + file.Name);
var path = (Application.persistentDataPath + "/" + Directory_path);
//Firestore Reference
storage = FirebaseStorage.DefaultInstance;
storageReference = storage.GetReferenceFromUrl("gs://houdini-ac884.appspot.com");
// File located on disk
string localFile = path.ToString();
StreamReader stream = new StreamReader(path);
// Create a reference to the file you want to upload
StorageReference riversRef = storageReference.Child("uploads/"+ file.Name);
// Upload the file to the path "uploads/newFile.meta"
riversRef.PutStreamAsync(stream.BaseStream)
.ContinueWith((task) => {
if (task.IsFaulted || task.IsCanceled) {
Debug.Log(task.Exception.ToString());
// Uh-oh, an error occurred!
}
else {
// Metadata contains file metadata such as size, content-type, and download URL.
StorageMetadata metadata = task.Result;
string md5Hash = metadata.Md5Hash;
Debug.Log("Finished uploading...");
Debug.Log("md5 hash = " + md5Hash);
}
});
}
Debug.Log(str);
} else {
Debug.Log("No Permissions");
Permission.RequestUserPermission(Permission.ExternalStorageRead);
return;
}

Related

Creating unique files in another directory

Currently i am taking in multiple .txt files from a directory i have specified (sourceDirectory). I am generating new .csv files with the same name as the .txt files - one .csv file for each .txt file.
However i want to generate these new files in another directory which i have specified (directoryPath). If i run my program once it creates these files in the initial directory, however if i run my program again it now generates the files in the destination directory.
The following is my code where i complete the above:
static void Main(string[] args)
{
string sourceDirectory = #"C:directoryWhereTXTFilesAre";
var txtFiles = Directory.EnumerateFiles(sourceDirectory, "*.txt", SearchOption.AllDirectories);
foreach (string currentFile in txtFiles)
{
readFile(currentFile);
}
string directoryPath = #"C:\destinationForCSVFiles";
}
I then create the new .csv files name based on the original .txt file like this:
static FileStream CreateFileWithUniqueName(string folder, string fileName, int maxAttempts = 1024)
{
var fileBase = Path.GetFileNameWithoutExtension(fileName);
var ext = Path.GetExtension(fileName);
// build hash set of filenames for performance
var files = new HashSet<string> (Directory.GetFiles(folder));
for (var index = 0; index < maxAttempts; index++)
{
// first try with the original filename, else try incrementally adding an index
var name = (index == 0)
? fileName
: String.Format("{0} ({1}){2}", fileBase, index, ext);
// check if exists
var fullPath = Path.Combine(folder, name);
string CSVfileName = Path.ChangeExtension(fullPath, ".csv");
if (files.Contains(CSVfileName))
continue;
// try to create the file
try
{
return new FileStream(CSVfileName, FileMode.CreateNew, FileAccess.Write);
}
catch (DirectoryNotFoundException) { throw; }
catch (DriveNotFoundException) { throw; }
catch (IOException)
{
}
}
I don't see why it's creating the .csv files initially in the same directory that the .txt files are in and then second time i run my code it creates them in the directoryPath.
Desired output: sourceDirectory left as it is with only .txt files and directoryPath to hold the .csv files.
The only other place i call CreateFileWithUniqueName is within my readFile method, the code is below:
using (var stream = CreateFileWithUniqueName(#"C:destinationFilePath", currentFile))
{
Console.WriteLine("Created \"" + stream.Name + "\"");
newFileName = stream.Name;
Globals.CleanedFileName = newFileName;
}
It seems that you are passing the full filename of the source file. This confuses the Path.Combine inside the CreateFileWithUniqueFilename because you are falling in this subtle remarks found on the documentation of Path.Combine
paths should be an array of the parts of the path to combine. If the
one of the subsequent paths is an absolute path, then the combine
operation resets starting with that absolute path, discarding all
previous combined paths.
You can fix it easily with
using (var stream = CreateFileWithUniqueName(#"C:\destinationFilePath",
Path.GetFileName(currentFile)))
{
Console.WriteLine("Created \"" + stream.Name + "\"");
newFileName = stream.Name;
Globals.CleanedFileName = newFileName;
}
Or better extract the filename without path inside the CreateFileWithUniqueName
static FileStream CreateFileWithUniqueName(string folder, string fileName, int maxAttempts = 1024)
{
var fileBase = Path.GetFileName(fileName);
fileBase = Path.GetFileNameWithoutExtension(fileBase);
var ext = Path.GetExtension(fileBase);
also, you should build your CSVfileName using the cleaned filename
var name = (index == 0)
? String.Format("{0}{1}", fileBase, ext);
: String.Format("{0} ({1}){2}", fileBase, index, ext);
var fullPath = Path.Combine(folder, name);
string CSVfileName = Path.ChangeExtension(fullPath, ".csv");
if (files.Contains(CSVfileName))
continue;

How to copy file from one library to another library using CSOM?

I need to copy a particular file from one library to another library.
At first, need to check if file is existing in that library.
If Existing, then need to overwrite file content and new sharepoint version should be updated for that document.
I need to do this using c# CSOM and sharepoint version is 2013.
Thanks in advance :)
public static void CopyDocuments(string srcUrl, string destUrl, string srcLibrary, string destLibrary, Login _login)
{
// set up the src client
SP.ClientContext srcContext = new SP.ClientContext(srcUrl);
srcContext.AuthenticationMode = SP.ClientAuthenticationMode.FormsAuthentication;
srcContext.FormsAuthenticationLoginInfo = new SP.FormsAuthenticationLoginInfo(_login.UserName, _login.Password);
// set up the destination context (in your case there is no needs to create a new context, because it would be the same library!!!!)
SP.ClientContext destContext = new SP.ClientContext(destUrl);
destContext.AuthenticationMode = SP.ClientAuthenticationMode.FormsAuthentication;
destContext.FormsAuthenticationLoginInfo = new SP.FormsAuthenticationLoginInfo(_login.UserName, _login.Password);
// get the list and items
SP.Web srcWeb = srcContext.Web;
SP.List srcList = srcWeb.Lists.GetByTitle(srcLibrary);
SP.ListItemCollection col = srcList.GetItems(new SP.CamlQuery());
srcContext.Load(col);
srcContext.ExecuteQuery();
// get the new list
SP.Web destWeb = destContext.Web;
destContext.Load(destWeb);
destContext.ExecuteQuery();
foreach (var doc in col)
{
try
{
if (doc.FileSystemObjectType == SP.FileSystemObjectType.File)
{
// get the file
SP.File f = doc.File;
srcContext.Load(f);
srcContext.ExecuteQuery();
// build new location url
string nLocation = destWeb.ServerRelativeUrl.TrimEnd('/') + "/" + destLibrary.Replace(" ", "") + "/" + f.Name;
// read the file, copy the content to new file at new location
SP.FileInformation fileInfo = SP.File.OpenBinaryDirect(srcContext, f.ServerRelativeUrl);
SP.File.SaveBinaryDirect(destContext, nLocation, fileInfo.Stream, true);
}
if (doc.FileSystemObjectType == SP.FileSystemObjectType.Folder)
{
// load the folder
srcContext.Load(doc);
srcContext.ExecuteQuery();
// get the folder data, get the file collection in the folder
SP.Folder folder = srcWeb.GetFolderByServerRelativeUrl(doc.FieldValues["FileRef"].ToString());
SP.FileCollection fileCol = folder.Files;
// load everyting so we can access it
srcContext.Load(folder);
srcContext.Load(fileCol);
srcContext.ExecuteQuery();
foreach (SP.File f in fileCol)
{
// load the file
srcContext.Load(f);
srcContext.ExecuteQuery();
string[] parts = null;
string id = null;
if (srcLibrary == "My Files")
{
// these are doc sets
parts = f.ServerRelativeUrl.Split('/');
id = parts[parts.Length - 2];
}
else
{
id = folder.Name;
}
// build new location url
string nLocation = destWeb.ServerRelativeUrl.TrimEnd('/') + "/" + destLibrary.Replace(" ", "") + "/" + id + "/" + f.Name;
// read the file, copy the content to new file at new location
SP.FileInformation fileInfo = SP.File.OpenBinaryDirect(srcContext, f.ServerRelativeUrl);
SP.File.SaveBinaryDirect(destContext, nLocation, fileInfo.Stream, true);
}
}
}
catch (Exception ex)
{
Log("File Error = " + ex.ToString());
}
}
}
Source: https://sharepoint.stackexchange.com/questions/114033/how-do-i-move-files-from-one-document-library-to-another-using-jsom
I strongly advise against using the approach suggested by Nikerym. You don't want to download the bytes only to upload them unmodified. It's slow and error-prone. Instead, use the built-in method provided by the CSOM API.
https://learn.microsoft.com/en-us/previous-versions/office/sharepoint-server/mt162553(v=office.15)?redirectedfrom=MSDN
var srcPath = "https://YOUR.sharepoint.com/sites/xxx/SitePages/Page.aspx";
var destPath = $"https://YOUR.sharepoint.com/sites/xxx/SitePages/CopiedPage.aspx";
MoveCopyUtil.CopyFileByPath(ctx, ResourcePath.FromDecodedUrl(srcPath), ResourcePath.FromDecodedUrl(destPath), false, new MoveCopyOptions());
ctx.ExecuteQuery();
You can configure the override behavior by adjusting the 4th and 5th arguments of the function signature.
[...]
bool overwrite,
MoveCopyOptions options
https://learn.microsoft.com/en-us/previous-versions/office/sharepoint-server/mt844930(v=office.15)

insert relative path for saving a zip file in asp.net

I wrote this function for creating a zip archive
protected void ImageButton_documenti_Click(object sender, ImageClickEventArgs e)
{
string path_cartella = #"d:\work\project1\temp\document";
string path_cartella_zip = #"d:\work\project1\temp\document_zip\";
path_cartella_zip = path_cartella_zip + "zip_documenti_al_" + System.DateTime.Now.ToString("ddMMyyyy") + ".zip";
//al click dell'immagine creo un file zip contenente tutte le cartelle dei documenti
using (ZipFile zip = new ZipFile())
{
try
{
zip.AddDirectory(path_cartella);
zip.Comment = "This zip was created at " + System.DateTime.Now.ToString("G");
zip.Save(path_cartella_zip);
operazione_ok.Visible = true;
operazione_ok.InnerText = "Procedura di zip attivata.";
}
catch (Exception errore)
{
elenco_errori.Visible = true;
elenco_errori.InnerText = errore.Message;
}
}
}
this function work fine in local but on my web server I don't know the absolute path and I want to change the "string_path_cartella" and "string_path_cartella_zip" for saving document with a relative path in "temp/document" folder
Try this:
string path_cartella = Server.MapPath("~/temp/document");
string path_cartella_zip = Server.MapPath("~/temp/document_zip");
Reference: http://msdn.microsoft.com/en-us/library/system.web.httpserverutility.mappath%28v=vs.110%29.aspx

Web API handle uploaded files for delete

ok I have this code that handle a file been upload through a simple web form
CustomMultipartFormDataStreamProvider provider = new CustomMultipartFormDataStreamProvider(#"C:\inetpub\wwwroot\myapp\Images");
//var provider = new MultipartFormDataStreamProvider(#"C:\inetpub\wwwroot\myapp\Images");
var Image = "";
var Dir = "";
var CurrentPath = "";
string UploadType = "";
string ImageName = "";
// Read the form data.
await Request.Content.ReadAsMultipartAsync(provider);
// Show all the key-value pairs.
foreach (var key in provider.FormData.AllKeys)
{
foreach (var val in provider.FormData.GetValues(key))
{
if (key == "uploadType") UploadType = val;
if (key == "imageName") ImageName = val;
//Trace.WriteLine(string.Format("{0}: {1}", key, val));
}
}
foreach (MultipartFileData file in provider.FileData)
{
//Debug.WriteLine(file.Headers.ContentDisposition.FileName);
//Debug.WriteLine("Server file path: " + file.LocalFileName);
Image = Path.GetFileName(file.LocalFileName);
Dir = Path.GetDirectoryName(file.LocalFileName);
CurrentPath = file.LocalFileName;
}
if (UploadType == "update")
{
File.Delete(Dir + "\\" + Image);
File.Move(CurrentPath, Dir + "\\" + Image);
Imagen = ImageName;
}
return Request.CreateResponse(HttpStatusCode.OK, Image);
as some docs mention using await will cause the read process to be async, my problem is that I need to know when the file has been saved into the folder cause I want to delete it after if the UploadType form field is == to update, but it seems like when try this line
File.Delete(Dir + "\\" + Image);
the image is has not been saved yet and I got an error that the image don't exist, so my question is, how I can tell or be sure the image is ready in the dir? how can I tell the async process ends, thanks for any help on this!!
File.Exists is the method you should use.
Aside You should be using Path.Combine instead of building the path with concatenation.

convert a zip file to MSI file/EXE file/windows installation file

I want to convert a zip file to MSI file/EXE file/windows installation file to install in remote computers in the network.
Up to now, I can make a zip file with user selected executable files and related support files etc. using the following C# code.
private void btnPackaging_Click(object sender, EventArgs e)
{
// make sure there are files to zip
if (listBox1.Items.Count < 1)
{
MessageBox.Show("There are no files queued for the zip operation", "Empty File Set");
return;
}
// make sure there is a destination defined
if (textBox1.Text == string.Empty)
{
MessageBox.Show("No destination file has been defined.", "Save To Empty");
return;
}
label3.Visible = true;
label3.Refresh();
// name the zip file whatever the folder is named
// by splitting the file path to get the folder name
string[] sTemp = textBox1.Text.Split('\\');
string sZipFileName = sTemp[sTemp.Length - 1].ToString();
// check to see if zipped file already exists
// user may rename it in the text box if it does.
FileInfo fi = new FileInfo(textBox1.Text + "\\" + sZipFileName + ".zip");
if (fi.Exists)
{
// move it to the folder
try
{
StringBuilder sb = new StringBuilder();
sb.Append("The file " + sZipFileName + " already exists. ");
sb.Append("You may rename it in the save to text box.");
MessageBox.Show(sb.ToString(), "Existing File Name");
textBox1.Focus();
return;
}
catch
{
MessageBox.Show("Rename the file or select a new location.", "File Error");
return;
}
}
// Check for the existence of the target folder and
// create it if it does not exist
if (!System.IO.Directory.Exists(textBox1.Text + "\\TempZipFile\\"))
{
System.IO.Directory.CreateDirectory(textBox1.Text + "\\TempZipFile\\");
}
// Set up a string to hold the path to the temp folder
string sTargetFolderPath = (textBox1.Text + "\\TempZipFile\\");
// Process the files and move each into the target folder
for (int i = 0; i < listBox1.Items.Count; i++)
{
string filePath = listBox1.Items[i].ToString();
FileInfo fi2 = new FileInfo(filePath);
if (fi2.Exists)
{
// move it to the folder
try
{
fi2.CopyTo(sTargetFolderPath + fi2.Name, true);
}
catch
{
// clean up if the operation failed
System.IO.Directory.Delete(sTargetFolderPath);
MessageBox.Show("Could not copy files to temp folder.", "File Error");
return;
}
}
}
// zip up the files
try
{
label3.Visible = true;
label3.Refresh();
string[] filenames = Directory.GetFiles(sTargetFolderPath);
// Zip up the files - From SharpZipLib Demo Code
using (ZipOutputStream s = new ZipOutputStream(File.Create(textBox1.Text + "\\" + sZipFileName + ".zip")))
{
s.SetLevel(9); // 0-9, 9 being the highest level of compression
byte[] buffer = new byte[4096];
foreach (string file in filenames)
{
ZipEntry entry = new ZipEntry(Path.GetFileName(file));
entry.DateTime = DateTime.Now;
s.PutNextEntry(entry);
using (FileStream fs = File.OpenRead(file))
{
int sourceBytes;
do
{
sourceBytes = fs.Read(buffer, 0, buffer.Length);
s.Write(buffer, 0, sourceBytes);
} while (sourceBytes > 0);
}
}
s.Finish();
s.Close();
}
// remove the progress bar
label3.Visible = false;
// clean up files by deleting the temp folder and its content
System.IO.Directory.Delete(textBox1.Text + "\\TempZipFile\\", true);
// Notify user
MessageBox.Show("Zip file " + textBox1.Text + " created.");
// empty everything
listBox1.Items.Clear();
textBox1.Text = string.Empty;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message.ToString(), "Zip Operation Error");
}
this.Dispose();
}
I don't have any idea, how to develop C# code to convert zip file into MSI file/EXE file/windows installation file.
Please help me, if anybody have an idea to solve this.
Thanks in Advance.

Categories