How to retrieve .dotx and .csv files from Resources Folder in C#? - c#

I have an application that uses a template file and a CSV file. It works perfectly fine since I do have the said files on my computer and I am referencing their paths. The only thing I want to do is that when the software is published and installed (and the said files are in the Resources folder so it would make them an embedded resource), the csv and template files would be copied to a directory folder that my program would use. Preferably the paths it would be copied to would be something like this : "C:\FILES" + template.dotx .
Now how do I get/retrieve the said files from the Resources Folder in my software into a new folder?

You could call
System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceNames();
And inspect which embedded resources are accessible. Then you can compare that against what you are passing in to see if you are indeed accomplishing what you expected to.
string FileExtractTo = "C:\FILES";
DirectoryInfo dirInfo = new DirectoryInfo(FileExtractTo);
if (!dirInfo.Exists())
dirInfo.Create();
using (Stream input = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName))
using (Stream output = File.Create(FileExtractTo + "\template.dotx"))
{
CopyStream(input, output);
}
CopyStream Method:
public static void CopyStream(Stream input, Stream output)
{
// Insert null checking here for production
byte[] buffer = new byte[8192];
int bytesRead;
while ((bytesRead = input.Read(buffer, 0, buffer.Length)) > 0)
{
output.Write(buffer, 0, bytesRead);
}
}

Related

Unzip .zip file from Assets folder to Internal Storage (Xamarin.Android)

So the question is pretty simple. I'm using Xamarin.Android and I have a zip file in the Assets folder named "MyZipFile.zip", which I want extracted to the following path: System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal);
It sounds simple enough, but I cannot figure out how to read the Asset into memory through the AssetManager and then unzip it at the targeted location.
Is there a simple way to do this?
The Android Java framework includes a Java.Util.Zip package, so without adding any additional app libraries, I directly use it instead of using C# framework code, thus no bloat that linking can not remove.
So basically you are creating an asset stream and feeding that to a ZipInputStream and iterating over each ZipEntry in that zip stream to either create directories or files to your destination path.
UnZipAssets
public void UnZipAssets(string assetName, string destPath)
{
byte[] buffer = new byte[1024];
int byteCount;
var destPathDir = new Java.IO.File(destPath);
destPathDir.Mkdirs();
using (var assetStream = Assets.Open(assetName, Android.Content.Res.Access.Streaming))
using (var zipStream = new ZipInputStream(assetStream))
{
ZipEntry zipEntry;
while ((zipEntry = zipStream.NextEntry) != null)
{
if (zipEntry.IsDirectory)
{
var zipDir = new Java.IO.File(Path.Combine(destPath, zipEntry.Name));
zipDir.Mkdirs();
continue;
}
// Note: This is deleting existing entries(!!!) for debug purposes only...
#if DEBUG
if (File.Exists(Path.Combine(destPath, zipEntry.Name)))
File.Delete(Path.Combine(destPath, zipEntry.Name));
#endif
using (var fileStream = new FileStream(Path.Combine(destPath, zipEntry.Name), FileMode.CreateNew))
{
while ((byteCount = zipStream.Read(buffer)) != -1)
{
fileStream.Write(buffer, 0, byteCount);
}
}
Log.Debug("UnZipAssets", zipEntry.Name);
zipEntry.Dispose();
}
}
}
Usage:
UnZipAssets("gameModLevels.zip", Path.Combine(Application.Context.CacheDir.AbsolutePath, "assets"));
Note: Even through the asset/zip steam is fast, depending upon number/size of the zip entries and the speed of the flash the entry is being written to, this should be done on a background thread as not to block UI thread and cause an ANR

Database file cannot be found

In my Windows Phone 8 C#/XAML .NET 4.5 project I'm using (with the help of LINQ-2-SQL) a local database (SQLite probably) created by another member of the team.
But when I run the application, it throws an exception:
The database file cannot be found. Check the path to the database. [ Data Source = C:\Data\Users\DefApps\AppData\{XXXXX-XXXXX-XXXXXX-XXXXX}\Local\database.sdf ]
The .sdf file with the database is in the project in /Database/database.sdf and the properties are set to Build action: Embedded resource & Copy to output directory: Copy always.
In the databaseContext.cs, which is a class used as context (not sure I'm naming it right, I'm new to linq-2-sql), the connection string is defined as:
Data Source=isostore:/database.sdf
Is this the right settings? What can I do to make it work?
You will have to move the database to isolated storage first. Heres how you could do it.
public static void MoveReferenceDatabase()
{
// Obtain the virtual store for the application.
IsolatedStorageFile iso = IsolatedStorageFile.GetUserStoreForApplication();
// Create a stream for the file in the installation folder.
using (Stream input = Application.GetResourceStream(new Uri("DutchMe.sdf", UriKind.Relative)).Stream)
{
// Create a stream for the new file in the local folder.
using (IsolatedStorageFileStream output = iso.CreateFile("DutchMe.sdf"))
{
// Initialize the buffer.
byte[] readBuffer = new byte[4096];
int bytesRead = -1;
// Copy the file from the installation folder to the local folder.
while ((bytesRead = input.Read(readBuffer, 0, readBuffer.Length)) > 0)
{
output.Write(readBuffer, 0, bytesRead);
}
}
}
}
Else
set the connection string to Data Source=appdata:/database.sdf . I am not very sure about the second solution.

Folder & Files Upload through ftp C#

i'm trying to learn something new about uploading through ftp connection to another host.
i know how to upload single file. but what if i want to upload full folder with its full subfolders and files that exists on it?
this is my one single file upload
private void Form1_Load(object sender, EventArgs e)
{
Upload("Test.txt");
}
public void Upload(string fileToUpload)
{
try
{
FileInfo toUpload = new FileInfo(fileToUpload);
FtpWebRequest request = (FtpWebRequest)WebRequest.Create("ftp://127.0.0.1/" + toUpload.Name);
MessageBox.Show(WebRequestMethods.Ftp.ListDirectory);
request.Method = WebRequestMethods.Ftp.UploadFile;
request.Credentials = new NetworkCredential("Uploader", "3635451");
Stream ftpStream = request.GetRequestStream();
FileStream file = File.OpenRead(fileToUpload);
int length = 1024;
byte[] buffer = new byte[length];
int bytesRead = 0;
do
{
bytesRead = file.Read(buffer, 0, length);
ftpStream.Write(buffer, 0, bytesRead);
}
while (bytesRead != 0);
file.Close();
ftpStream.Close();
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
}
}
i google'd alot about uploading folder but i have just failed
thank you in advance.
You could use the WinSCP library. It is free, and supports FTP as well as SFTP. I have found it easy to use, and works flawlessly.
The PutFiles method will process an entire folder, including sub-folders. It also has a SynchronizeDirectories method.
The answer is you cannot.
You may be interested by libraries for doing such operations, if not you can look at their source code.
If you want to upload a folder you have to create the folder on your FTP and then copy each file one by one.
Example of a folder on local:
/Folder/File1.txt
/Folder/File2.txt
If you want to upload the folder "Folder".
Create directory in FTP
Open the FTP directory
Copy "File1.txt"
Copy "File2.txt"

Valums uploader and DB save on multiple files

I am using valums uploader with an ashx file example that I found & tweeked, and want to save data from each file to the db when I upload, stepping through the code , there doesn't seem any way to differentiate which file is uploaded in which order , watching certain variable , the code jumps all over the place. It works fine for single files but more than 1 is an issue. Also, context.Request.Files.Count is always 0
byte[] buffer = new byte[request.ContentLength];
fileName = request.RawUrl.Split('=')[1];
fmt = Path.GetExtension(fileName);
using (BinaryReader br = new BinaryReader(request.InputStream))
br.Read(buffer, 0, buffer.Length);
File.WriteAllBytes(StorageRoot + request["qqfile"], buffer);
success = false;
context.Response.Write("{success:true}");
HttpContext.Current.ApplicationInstance.CompleteRequest();
Any ideas?
I've used valums uploader without problem. Different browsers upload files in different ways. IE will use an file upload html control, whilst Firefox & Chrome can do it Ajax style. I wrote my own upload handler, but the first thing you need to do is figure which method was used.
I do this like this:
if (HttpContext.Current.Request.QueryString["qqfile"] != null)
file = new UploadedFileXhr();
else if (HttpContext.Current.Request.Files.Count > 0)
file = new UploadedFileForm();
else
return new UploadResult("Request was not valid.");
An XHR upload means you read from the input buffer like so:
int read = HttpContext.Current.Request.InputStream.Read(buffer, 0, buffer.Length);
while (read == buffer.Length)
{
ms.Write(buffer, 0, buffer.Length);
read = HttpContext.Current.Request.InputStream.Read(buffer, 0, buffer.Length);
}
ms.Write(buffer, 0, read);
A file upload is simpler like so:
UploadResult result = new UploadResult(true);
result.Stream = _File.InputStream;
result.Name = System.IO.Path.GetFileName(_File.FileName);
Even if you add multiple files in the client, each file is uploaded individually.

c# gzip - keep extension on original file but remove when compressing

Basically I'm trying to compress a file "sample.doc" into the .gz file format. When this happens, it is told to remove the extension of the file so instead of appearing as
"sample.doc.gz" it appears as "sample.gz". However, when the file is extracted it has also lost its ".doc" file extension. eg. filename is just "sample". Any ideas?
using System;
using System.IO;
using System.IO.Compression;
using System.Text;
namespace gzipexample
{
class Program
{
public static void Main()
{
CompressFile(#"C:\sample.doc");
}
//Compresses the file into a .gz file
public static void CompressFile(string path)
{
string compressedPath = path;
Console.WriteLine("Compressing: " + path);
int extIndex = compressedPath.LastIndexOf(".");
FileStream sourceFile = File.OpenRead(path);
FileStream destinationFile = File.Create(compressedPath.Replace(compressedPath.Substring(extIndex), "") + ".gz");
byte[] buffer = new byte[sourceFile.Length];
sourceFile.Read(buffer, 0, buffer.Length);
using (GZipStream output = new GZipStream(destinationFile,
CompressionMode.Compress))
{
Console.WriteLine("Compressing {0} to {1}.", sourceFile.Name,
destinationFile.Name, false);
output.Write(buffer, 0, buffer.Length);
}
// Close the files.
sourceFile.Close();
destinationFile.Close();
}
}
}
If I'm understanding your question correctly, there is no solution as stated. A gzip'ed file (at least, a file gzip'ed the way you're doing it) doesn't store its name, so if you compress a file named sample.doc and the output is named sample.gz, the ".doc" part is gone forever. That's why if you compress a file with the gzip command-line utility, it the compressed version sample.doc.gz.
In some constrained situations, you might be able to guess an appropriate extension by looking at the contents of the file, but that isn't very reliable. If you just need compression, and the file format isn't constrained, you could just build a .zip file instead, which does store filenames.

Categories