How to read in a file from anywhere (relative path) - c#

I am currently writing a language translator application. I want to support the ability to choose a file, read in the contents of the file into the entry box, and output the translation once the appropriate button is pressed.
I am using the plugin 'Xam.Plugin.FilePicker' to allow the user to choose a file, which is working. When the user chooses a file, I have it so that the name of the file is displayed on the screen. However, problems occur when trying to read in the file into the entry box, which I believe is linked to the application not being able to determine the path of the file - currently the application tries to read in the file from the location where Visual Studio 2017 is located.
I have tried several approaches, some of which are detailed in the below:
How to get relative path of a file in visual studio?
How to read from a file using C# code?
I have also tried:
var file = await CrossFilePicker.Current.PickFile();
if (file != null) {
string filePath =
Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
string filename = Path.Combine(filePath, file.FileName);
using (var reader = new StreamReader(filename)) {
entText= reader.ReadToEnd();
}
}
Where entText is the name of the entry box in the MainPage.xaml.cs file
Below is the code I have so far. I have removed the above code from the file and, while it was giving me a path, the path was either the path in which Visual Studio 2017 is located in or some other path. Either way, the application couldn't find the file.
C# code:
private async void BtnReadFile_Clicked(object sender, EventArgs e)
{
string fileName;
string fileText;
string filePath;
// Allows the user to choose a file from any location
var file = await CrossFilePicker.Current.PickFile();
if (file != null)
{
lblFileRead.Text = file.FileName; // Displays the name of the file
}
}
Xaml code:
Entry box:
<Entry x:Name="entText" Placeholder="Enter text to translate" Keyboard="Text"
HeightRequest="200" WidthRequest="250" TextChanged="EntText_TextChanged" />
Button to read in file
<Button x:Name="btnReadFile" Text="Read in file" Clicked="BtnReadFile_Clicked" />
To conclude, I want to be able to read in a file from any location, not just a predetermined location i.e.
The user should be able to read in a file from "C:/Documents/files", "C:/Downloads/", etc.

I guess you are using Xamarin? You are not supposed to have access to the file itself. You can get the name and you can get the contents.
You can get the file's contents by accessing file.DataArray instead of using the traditional file access. So what the actual path of the file is, is none of your business.

the CrossFilePicker returns a full path reference to the selected file. So you don't have to combine it with any other path.
Refer to the example from the project website
It shows exactly what you try to do - read the file content and output it.
try
{
FileData fileData = await CrossFilePicker.Current.PickFile();
if (fileData == null)
return; // user canceled file picking
string fileName = fileData.FileName;
string contents = System.Text.Encoding.UTF8.GetString(fileData.DataArray);
System.Console.WriteLine("File name chosen: " + fileName);
System.Console.WriteLine("File data: " + contents);
}
catch (Exception ex)
{
System.Console.WriteLine("Exception choosing file: " + ex.ToString());
}
You just have to replace the Console output by putting the value of contents to your control.

You are setting filePath to
Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)
when it should instead be:
file.FilePath
since the latter is the actual location of the file.

Related

Get image file path from resources

I have an image file day.jpg in Resources folder and I want to access it in the code as string path not as byte[] img
Here's what I have tried.
string dayWallpaper = Assembly.GetExecutingAssembly().Location + #"..\..\Resources\day.jpg";
// Didn't found it
string dayWallpaper = Resource.day;
// Outputs byte[] and gives me an error
Then I tried to convert the byte[] to String didn't work as well
static byte[] SliceMe(byte[]? source, int pos)
{
byte[]? destfoo = new byte[source.Length - pos];
Array.Copy(source, pos, destfoo, 0, destfoo.Length);
return destfoo;
}
static string ByteToPath(path)
{
String file = Encoding.Unicode.GetString(SliceMe(path, 24)).TrimEnd("\0".ToCharArray());
return file
}
Outputs black screen
Later I search for the file
if (File.Exists(dayWallpaper))
{
do stuff
}
else
{
Console.WriteLine("File does not exists");
}
And gives me the else statement.
In the answer you posted to your question, the fact that your relative path works is an "accident" that would fail on any other device deploying your app because without the existence of the source code project the path doesn't exist. One good option is to mark the day.jpg file as Copy to Output Directory at which point most installer bundlers will pick it up and deploy it in your setup.exe, msi etc. If you are specifically using the Visual Studio IDE, you would do it like this:
Now, at runtime, to acquire the path to the copied file:
var srce = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Resources", "day.jpg");
However, there is more work to be done, because you state that you "want to store the image in a folder in the executable and the user could add more images later on." The present location of the file is not suitable for that purpose, so I would recommend the additional step of creating an AppData entry for the user to store their created content.
// Obtain a folder that "the user could add to later on".
var appData =
Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
typeof(Program).Assembly.GetName().Name
);
Directory.CreateDirectory(appData);
Since you mention wanting to store the day.jpg image in that folder, go ahead and copy it to the AppData location (if not already there from a previous run of your app).
var dest = Path.Combine(appData, "day.jpg");
// Copy the image (if it's not there already) into folder that the user can add to.
if (!File.Exists(dest))
{
File.Copy(
sourceFileName: srce,
destFileName: dest
);
}
Alternatively, you could set the BuildAction to EmbeddedResource and manipulate the file as a byte stream and achieve the same end result.
I managed to do it this way
string resourcePath = Path.GetFullPath(Assembly.GetExecutingAssembly().Location + #"\..\..\..\..\Resources");
string dayWallpaper = resourcePath + #"\day.jpg";

C# ASP System.IO.Compression - Unauthorized access exception when using zipArchive.CreateEntryFromFile for multiple files()

I have the following lines of code that work for creating a zip using ZipFile.CreateFromDirectory(selectedFile, zipPath)
if (selectedFolder == string.Empty)
{
Console.WriteLine("Invalid folder, try again");
}
else
{
Console.WriteLine("\nSelect zipfile name: ");
var zipName = Console.ReadLine();
// Also available: extractToDirectory
var zipPath = #"C:\Users\User\Documents\Dev\" + zipName + ".zip";
ZipFile.CreateFromDirectory(selectedFolder, zipPath);
However, the following code which should for all intents and purposes do the same thing except for multiple files being archived into a single zip folder refuses to work:
public static void CreateZipFile(string folderToCreateZip, IEnumerable<string> files)
{
var zipPath = folderToCreateZip + "\\test6.zip";
// Create a new ZIP in this location
using (var zip = ZipFile.Open(zipPath, ZipArchiveMode.Create))
{
foreach (var file in files)
{
// Add entry for files
zip.CreateEntryFromFile(file, zipPath, CompressionLevel.Optimal);
}
}
// Dispose of zip object after files have been zipped
//zip.Dispose();
}
var zip == ZipArchive zip
I've tried disabling read-only mode on the folders where the zip should get created, but I don't think this matters since the prior function with CreateFromDirectory() works fine. I've also tried creating a ZIP on desktop, but I get the same error.
This is the exception I'm getting:
As a note, I noticed that it does initially create the zip despite this error, just that it cannot add anything to it unlike CreateFromDirectory() can due to the folder either being in use, no permissions to that area or the folder already existing. Is there a way I can get CreateEntryFromFile() working or an alternative that would work for multiple files?
I had the same problem. The solution was post the full path name at the destinationArchiveFileName parameter (and also a write alowed path). For example c:\my apps folder\my app\my temp\zipfile.zip

How to get the fullname of the file stored in the temp folder in asp.net mvc 5 app?

I have an app written using c# on the top on ASP.NET MVC 5 framework. One of my pages allow a user to upload file to the server. So I use HttpPostedFileBase to upload the file to the server.
However, instead on saving the file to a permanent place, I am hoping be able to extract the fullname of the file and work on it before moving it to a permanent place.
How can I get the temp full-name of the uploaded file?
I tried the following, but the check File.Exists(tempFullname) always fails.
public string GetFullname(HttpPostedFileBase file)
{
string tempFullname = Path.GetTempPath() + file.FileName;
if(File.Exists(tempFullname))
{
return tempFullname;
}
return string.Empty;
}
I also tried the following but temp.Length throw an exception as the file does not exists
public string GetFullname(HttpPostedFileBase file)
{
string temp = new FileInfo(file.FileName);
if(temp.Length > 0)
{
return tempFullname;
}
return string.Empty;
}
To get the full name of need to save the file first, i can't get the location of a file if you don't save it first!
var filePath = Path.Combine(Server.MapPath("<A folder you want>"), file.FileName);
file.Save(filePath);
In this way, filePath is the full path of your file

How do you save and preview an HTML file from temp folder?

I'm developing an HTML editor in C# where you can edit your code in the FastColoredTextBox.dll component. You will have this option in the MenuStrip called "Preview in browser" and there will be a drop down item called "Chrome" and "Iexplore" etc. I want it instead of saving the file, i want it to make a file in the Temp folder and preview it. and after we've modified the code again, the file will update as we preview it again. This is what i have so far:
string location = null;
string sourcecode = FastColoredTextBox1.Text;
location = System.IO.Path.GetTempPath() + "\\TempSite.html";
using (StreamWriter writer = new StreamWriter(location, true))
{
writer.Write(sourcecode);
writer.Dispose();
}
try
{
System.Diagnostics.Process.Start("chrome.exe", location);
}
catch (Exception ex)
{
Interaction.MsgBox(ex.Message);
}
How do you achieve this?
Q: How do you save and preview an HTML file from temp folder?
A: You're already doing precisely that :)
Q: Why does my browser keep re-displaying the original image?
A: Because your browser is reading the html from cache.
SOLUTION:
Give your new file a different name. For example:
location = System.IO.Path.GetTempPath() + Path.GetTempFileName() + ".html";
... OR ...
location = Path.GetTempPath() + Guid.NewGuid().ToString() + ".html";
You can also simply hit <F5> to refresh, <Ctl-Shift-Del> to clear cache, or disable cache in your browser.

Create text file in a given folder

I am developing a windows 8 app using Microsoft visual studio 2013. I needed to store the user entered data in a text file. I have wrote the following code segment to create the file and its working. But the text file is created in C:\Users...... I want to create the text file in a given folder. How can I modify my code to create the file in a folder where I specify.
StorageFile sampleFile;
const string fileName = "Sample.txt";
This is how you can create a file in C temp folder
String folderPath = #"C:/temp";
FileStream fs = new FileStream(folderPath + "\\Samplee.txt",FileMode.OpenOrCreate, FileAccess.Write);
As told before, Universal apps are sandboxed which means you can't write a file in an arbitrary folder.
You should take a look at the File access sample on how to do it.
Also, you should take a look at the ApplicationData which gives you a lot of choices for saving user entered data. Is it temporary, do you want it to be synced, is it a setting? There sure is a property that suits your needs.
edit: from http://msdn.microsoft.com/en-us/library/windows/apps/windows.storage.applicationdata.localfolder.aspx this is what you should do
var applicationData = Windows.Storage.ApplicationData.current;
var localFolder = applicationData.localFolder;
// Write data to a file
function writeTimestamp() {
localFolder.createFileAsync("dataFile.txt", Windows.Storage.CreationCollisionOption.replaceExisting)
.then(function (sampleFile) {
var formatter = new Windows.Globalization.DateTimeFormatting.DateTimeFormatter("longtime");
var timestamp = formatter.format(new Date());
return Windows.Storage.FileIO.writeTextAsync(sampleFile, timestamp);
}).done(function () {
});
}
You need to set the directory where you want to save the file.
Try this
string dirctory = #"D:\Folder Name"; //This is the location where you want to save the file
if (!Directory.Exists(dirctory))
{
Directory.CreateDirectory(dirctory);
}
File.WriteAllText(Path.Combine(dirctory, "Sample.txt"), "Text you want to Insert");

Categories

Resources