MonoDroid: Path to Assets to unzip a file with .NET framework - c#

I am using the SharpZip .NET Zip Library to unzip a file found in the Assets/MyZipFolder folder.
I need to get the full path so that I can use the following:
ZipInputStream s = new ZipInputStream(File.OpenRead(_zipFile))
How do I get the path to Assets/MyZipFolder/MyZip.zip to pass to a .NET File.OpenRead command?

From your Context you can simply open a read stream using:
using (var stream = Context.Assets.Open("MyZipFolder/MyZip.zip"))
{
var s = new ZipInputStream(stream);
// do read here ...
}
Be careful that the file is marked as an AndroidAsset for build action, the absolute path is: "file:///android_asset" and remember that file names in android are case sensitive.

Related

UWP C# Windows IoT Read Text Line to Process Word [duplicate]

I am trying to read a text file named thedata.txt that has a list of words that I want to use in a hangman game. I have tried different ways, but I can't figure out where the file gets placed, if at all when the app runs. I added the file to my project, and I have tried setting the build properties to content, and then embedded resource, but can't find the file. I have made a Windows 10 universal app project. The code I tried looks like this:
Stream stream = this.GetType().GetTypeInfo().Assembly.GetManifestResourceStream("thedata.txt");
using (StreamReader inputStream = new StreamReader(stream))
{
while (inputStream.Peek() >= 0)
{
Debug.WriteLine("the line is ", inputStream.ReadLine());
}
}
I get exceptions.
I also tried to list the files in another directory:
string path = Windows.Storage.ApplicationData.Current.LocalFolder.Path;
Debug.WriteLine("The path is " + path);
IReadOnlyCollection<StorageFile> files = await Windows.Storage.ApplicationData.Current.LocalFolder.GetFilesAsync();
foreach (StorageFile file2 in files)
{
Debug.WriteLine("Name 2 is " + file2.Name + ", " + file2.DateCreated);
}
I don't see the file there either...I want to avoid hard coding the list of names in my program. I'm not sure what the path that the file is placed.
the code is very simple, you just have to use a valid scheme URI (ms-appx in your case) and transform your WinRT InputStream as a classic .NET stream :
var file = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///thedata.txt"));
using (var inputStream = await file.OpenReadAsync())
using (var classicStream = inputStream.AsStreamForRead())
using (var streamReader = new StreamReader(classicStream))
{
while (streamReader.Peek() >= 0)
{
Debug.WriteLine(string.Format("the line is {0}", streamReader.ReadLine()));
}
}
For the properties of the embedded file, "Build Action" must be set to "Content" and "Copy to Ouput Directory" should be set to "Do not Copy".
You can't use classic .NET IO methods in Windows Runtime apps, the proper way to read a text file in UWP is:
var file = await ApplicationData.Current.LocalFolder.GetFileAsync("data.txt");
var lines = await FileIO.ReadLinesAsync(file);
Also, you don't need a physical path of a folder - from msdn :
Don't rely on this property to access a folder, because a file system
path is not available for some folders. For example, in the following
cases, the folder may not have a file system path, or the file system
path may not be available. •The folder represents a container for a
group of files (for example, the return value from some overloads of
the GetFoldersAsync method) instead of an actual folder in the file
system. •The folder is backed by a URI. •The folder was picked by
using a file picker.
Please refer File access permissions for more details.
And Create, write, and read a file provides examples related with File IO for UWP apps on Windows 10.
You can retrieve a file directly from your app's local folder by using an app URI, like this:
using Windows.Storage;
StorageFile file = await StorageFile.GetFileFromApplicationUriAsync("ms-appdata:///local/file.txt");

Getting DLL's 'Content' file from web app

I have a class library that has some text files with Build Action = Content. These text files are read by a function within the class library. To get the location of the text files I use this:
var filePath = System.IO.Path.Combine(
AppDomain.CurrentDomain.BaseDirectory,
"AFolder",
"textFileName.txt");
var fileContent = System.IO.File.ReadAllText(filePath);
I have successfully retrieved the content of the text file when I called the function from a unit test. The text file is in C:\MySolution\MyProject.Test\bin\Debug\AFolder\textFileName.txt.
I have another web app that references this class library. When I called the function to read the text file from the web app, it couldn't find the text file because it tried to get the file from C:\MySolution\MyProject.Web\AFolder\textFileName.txt while the text file is actually in C:\MySolution\MyProject.Web\bin\AFolder\textFileName.txt.
So my problem is calling AppDomain.CurrentDomain.BaseDirectory doesn't always work. What should I use instead to get the folder location?
Found the answer from the link on the right by using System.Reflection.Assembly.GetExecutingAssembly().CodeBase:
var libPath = System.IO.Path.GetDirectoryName(
new Uri(
System.Reflection.Assembly.GetExecutingAssembly().CodeBase
).LocalPath
);
var filePath = System.IO.Path.Combine(
libPath,
"AFolder",
"textFileName.txt");
var fileContent = System.IO.File.ReadAllText(filePath);
You can try System.WebHttpRuntime.BinDirectory to get the physical path to the /bin directory for the current application.
EDIT 1:
Another way to get without using System.Web is using AppDomain.CurrentDomain.SetupInformation.PrivateBinPath, this property provides list of directories under the application base directory that are probed for private assemblies.

How to get the file relative path in c# service project?

I have this code:
Stream stream = new StreamReader("~/quartz.xml").BaseStream;
Q1:What is the "~" symbol specify path in C#?
Q2:How to get the "~" directory in C# service project?
Q3:Does it mean the bin exe directory or project name directory?
The quartz.xml file in my Windows service project located in two position:
D:\jsptpd\Code\jsptpdJobScheduler\jsptpdJobScheduler\bin\Debug
D:\jsptpd\Code\jsptpdJobScheduler\jsptpdJobScheduler
Sure the path will change everytime!So get the relative path is better.
Just omit it entirely:
Stream stream = new StreamReader("quartz.xml").BaseStream;
The default directory is the .exe's directory.
Per the OP's edit to the question:
Go to View > Solution Explorer. Right-click the file in question, then choose Properties. Change the Copy To Output Directory option to Copy Always. Then use the code above.
if we use(../quartz.xml):
the StreamReader read path is(not the file actual path):
C:\Windows\quartz.xml
if we use(quartz.xml):
the StreamReader read path is(not the file actual path):
C:\Windows\system32\quartz.xml
This is the way to find the file relative path:
string assemblyFilePath = Assembly.GetExecutingAssembly().Location;
string assemblyDirPath = Path.GetDirectoryName(assemblyFilePath);
string configFilePath = assemblyDirPath + "\\quartz.xml";
Stream stream = new StreamReader(configFilePath).BaseStream;
So the path is(you can specify either of two):
D:\jsptpd\Code\jsptpdJobScheduler\jsptpdJobScheduler\bin\Debug\quartz.xml

Reading an embedded text file

I have created a full project which works perfectly. My problem concerns the setup project. When I use it on another computer, the text file cannot be found even if they are inside the resource folder during the deployment!
How can I ensure that my program will find those text files after installing the software on another computer!
I have been looking for this solution but in vain. Please help me sort this out. If I can get a full code that does that i will be very happy!
FIrst set the build action of the text file to "EmbeddedResource".
Then to read the file in your code:
var assembly = Assembly.GetExecutingAssembly();
var resourceName = "AssemblyName.MyFile.txt";
using (Stream stream = assembly.GetManifestResourceStream(resourceName))
{
using (StreamReader reader = new StreamReader(stream))
{
string result = reader.ReadToEnd();
}
}
If you can't figure out the name of the embedded resource do this to find the names and it should be obvious which your file is:
assembly.GetManifestResourceNames();
This is assuming you want the text file to be embedded in the assembly. If not, then you might just want to change your setup project to include the text file during the installation.
Assuming you mean that you have a file in your project that you've set as an EmbeddedResource, you want
using (var stream = Assembly.GetExecutingAssembly()
.GetManifestResourceStream(path))
{
...
}
where path should be the assembly name followed by the relative path to your file in the project folder hierarchy. The separator character used is the period ..
So if you have an assembly called MyCompany.MyProject and then in that project you have a folder Test containing Image.jpg, you would use the path MyCompany.MyProject.Test.Image.jpg to get a Stream for it.
create this function to read whatever embedded resource text file you have :
public string GetFromResources(string resourceName)
{
Assembly assem = this.GetType().Assembly;
using (Stream stream = assem.GetManifestResourceStream(resourceName))
{
using (var reader = new StreamReader(stream))
{
return reader.ReadToEnd();
}
}
}

Taking a copy of an Excel template that is saved in the Solution

I have this solution structure:
I'd like to take a copy of this template and then save a copy of it to a network drive. Using System.IO I've previously using this code to take a copy of a file:
string templateFilePath = #"\\blah\blah\blah\blah\Temp.xlsx"; //<<<< X
string exportFilePath = #"\\blah\blah\blah\blah\Results.xlsx";
File.Copy(templateFilePath, exportFilePath, true);
Because the template is saved within the solution do I still need to specify the complete pathway or is there a shorter was of referencing this file?
You'll need to specify the full path of the file or the relative path in regards to where the executable is running. So you can set targetFileName = ".\template.xlsx
another way to get the file is to mark the Build Action in the properties of the file and set it to Embedded Resource. then use the following code to get the stream. Not sure if the stream will help you or not.
Assembly asm = Assembly.GetExecutingAssembly();
string file = string.Format("{0}.Template.xlsx", asm.GetName().Name);
var ms = new MemoryStream();
Stream fileStream = asm.GetManifestResourceStream(file);

Categories