Read files in WP8 - c#

i have a problem with reading file in WP8.
string text;
IStorageFolder applicationFolder = ApplicationData.Current.LocalFolder;
IStorageFile storageFile = await applicationFolder.GetFileAsync("MyFile.txt");
IRandomAccessStream accessStream = await storageFile.OpenReadAsync();
using (Stream stream = accessStream.AsStreamForRead((int)accessStream.Size))
{
byte[] content = new byte[stream.Length];
await stream.ReadAsync(content, 0, (int)stream.Length);
text = Encoding.UTF8.GetString(content, 0, content.Length);
}
return text;
Sometimes the storagefile or the accessStream crash without a reason.
If I debug them, it works.
I have no idea why. Can anyone help me?

I'm using this piece of code. The result will be the texts within your txt file, shortened into a string, so let's say your txt file contains this.
This
is
a test.
Result will be
This\nis\na\test.
Then, all you need to do is to split them up.
string result = null;
IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication();
if (store.FileExists("services.txt"))
{
using (var stream = new IsolatedStorageFileStream("services.txt", FileMode.Open, store))
{
using (var fileReader = new StreamReader(stream))
{
result = fileReader.ReadToEnd();
}
}
}
This is how i split the message.
string[] tmp = result.Split(new char[] { '\r', '\n', '.' });
foreach (string str in tmp)
{
System.Diagnostics.Debug.WriteLine(str);
}
Hope this helps.

Related

How to convert a file into byte array in memory?

Here is my code:
public async Task<IActionResult> Index(ICollection<IFormFile> files)
{
foreach (var file in files)
uploaddb(file);
var uploads = Path.Combine(_environment.WebRootPath, "uploads");
foreach (var file in files)
{
if (file.Length > 0)
{
var fileName = ContentDispositionHeaderValue.Parse(file.ContentDisposition).FileName.Trim('"');
await file.SaveAsAsync(Path.Combine(uploads, fileName));
}
}
}
Now I am converting this file into byte array using this code:
var filepath = Path.Combine(_environment.WebRootPath, "uploads/Book1.xlsx");
byte[] fileBytes = System.IO.File.ReadAllBytes(filepath);
string s = Convert.ToBase64String(fileBytes);
And then I am uploading this code into my nosql database.This is all working fine but the problem is i don't want to save the file. Instead of that i want to directly upload the file into my database. And it can be possible if i can just convert the file into byte array directly without saving it.
public async Task<IActionResult> Index(ICollection<IFormFile> files)
{
foreach (var file in files)
uploaddb(file);
var uploads = Path.Combine(_environment.WebRootPath, "uploads");
foreach (var file in files)
{
if (file.Length > 0)
{
var fileName = ContentDispositionHeaderValue.Parse(file.ContentDisposition).FileName.Trim('"');
///Code to Convert the file into byte array
}
As opposed to saving the data as a string (which allocates more memory than needed and might not work if the binary data has null bytes in it), I would recommend an approach more like
foreach (var file in files)
{
if (file.Length > 0)
{
using (var ms = new MemoryStream())
{
file.CopyTo(ms);
var fileBytes = ms.ToArray();
string s = Convert.ToBase64String(fileBytes);
// act on the Base64 data
}
}
}
Also, for the benefit of others, the source code for IFormFile can be found on GitHub
You can just write a simple extension:
public static class FormFileExtensions
{
public static async Task<byte[]> GetBytes(this IFormFile formFile)
{
await using var memoryStream = new MemoryStream();
await formFile.CopyToAsync(memoryStream);
return memoryStream.ToArray();
}
}
Usage
var bytes = await formFile.GetBytes();
var hexString = Convert.ToBase64String(bytes);
You can use the following code to convert it to a byte array:
foreach (var file in files)
{
if (file.Length > 0)
{
var fileName = ContentDispositionHeaderValue.Parse(file.ContentDisposition).FileName.Trim('"');
using (var reader = new StreamReader(file.OpenReadStream()))
{
string contentAsString = reader.ReadToEnd();
byte[] bytes = new byte[contentAsString.Length * sizeof(char)];
System.Buffer.BlockCopy(contentAsString.ToCharArray(), 0, bytes, 0, bytes.Length);
}
}
}
You can retrieve your file by using the Request.Form already implemented (as image for instance) :
var bytes = new byte[Request.Form.Files.First().Length];
var hexString = Convert.ToBase64String(bytes);
Hope it help

Decompressing a zipfile into memory stream - C#

I have written code to store the encoded string of zip file into temp path and now I want to store the encoded zipfile string to memorystream instead of temp path. Can someone please help me how to read the stream and pass it as a string to ZipFile class...I am using DOTNETZIP library to unpack password protested file.
Please see below my code.
string tempPath = Path.GetTempPath();
foreach (ActivityMimeAttachment a in attachments.Entities)
{
if (a.FileName.EndsWith(".zip", StringComparison.OrdinalIgnoreCase))
{
string strcontent = a.Body;
byte[] filecontent = Convert.FromBase64String(strcontent); // unpack the base-64 to a blob
File.WriteAllBytes(tempPath + a.FileName, filecontent); // Working code creates a zip file
string attachmentfile = tempPath + a.FileName;
using (ZipFile zip = new ZipFile(attachmentfile))
{
foreach (ZipEntry entry in zip.Entries)
{
if ((entry.FileName.EndsWith(".xml", StringComparison.OrdinalIgnoreCase)) ||
(entry.FileName.EndsWith(".pdf", StringComparison.OrdinalIgnoreCase)))
{
entry.ExtractWithPassword(tempPath, "password");
FileStream inFile;
byte[] binaryData;
string file = tempPath + entry.FileName;
inFile = new FileStream(file, FileMode.Open, FileAccess.Read);
binaryData = new Byte[inFile.Length];
long bytesRead = inFile.Read(binaryData, 0,
(int)inFile.Length);
inFile.Close();
You'll want to convert your file content to a memory stream (Stream filestream = new MemoryStream(filecontent)) then use ZipFile.Read(fileStream). Then use a StreamReader to get the contents out as a string. So try something like this (note it's untested):
string myString;
byte[] filecontent = Convert.FromBase64String(strcontent);
using (var filestream = new MemoryStream(filecontent))
{
using (ZipFile zip = ZipFile.Read(filestream))
{
foreach (ZipEntry entry in zip.Entries)
{
if ((entry.FileName.EndsWith(".xml", StringComparison.OrdinalIgnoreCase)) ||
(entry.FileName.EndsWith(".pdf", StringComparison.OrdinalIgnoreCase)))
{
using (var ms = new MemoryStream())
{
entry.ExtractWithPassword(ms, "password");
ms.Position = 0;
var sr = new StreamReader(ms);
myString = sr.ReadToEnd();
}
...
If the results should be a base64 string, do this:
entry.ExtractWithPassword(ms, "password");
ms.Position = 0;
myString = Convert.ToBase64String(ms.ToArray());
You may or may not have to reset the stream position, but it's good practice to.
Now you can use the results as a string without having to write to a file first.

Stream was not writeable (StreamWriter)

I'm trying to remove specific line from file on IsolatedStorage but I'm still receiving the "Stream was not writeable" from following method:
public async static void RemoveFavoriteFromFile(int id)
{
string favoriteFilename = Globals.FavoriteFilepath;
StorageFolder local = Windows.Storage.ApplicationData.Current.LocalFolder;
var folder = await local.GetFolderAsync("DataFolder");
var file = await folder.OpenStreamForReadAsync(Globals.FavoriteFilepath);
using (StreamReader sr = new StreamReader(file))
{
using (StreamWriter sw = new StreamWriter(file))
{
string line = null;
while ((line = sr.ReadLine()) != null)
{
if (String.Compare(line, id.ToString()) == 0)
continue;
sw.WriteLine(line);
}
}
}
}
on line using (StreamWriter sw = new StreamWriter(file))
Could anybody help me please?
Thanks in advance
EDIT: I would mainly ask you to advice me how to remove specific line from existing file, no matter what I created already. Main issue for me in meaning of understanding is that how to write/edit a file which I firstly need to read for finding the specific line.
Reading and writing to the same file at the same time is always a bad idea.
Either write to a swap file "filename_swap.txt". After it has finished writing the entire file, delete the original file and rename the "filename_swap.txt" to the original file (basically replacing it).
Or you can read the entire file into a buffer, close the file. Make your changes to said buffer then open the file again for writing. This time, write the entire content of the modified buffer.
So lets modularize your program
using System.Threading.Tasks;
// read the specific file into a string buffer
private async Task<string> ReadFileIntoBuffer(string fileName)
{
string buffer = ""; // our buffer
StorageFolder local = Windows.Storage.ApplicationData.Current.LocalFolder; // local folder
var folder = await local.GetFolderAsync("DataFolder"); // sub folder
// open the file for reading
using (Stream s = await folder.OpenStreamForReadAsync(fileName))
{
using (StreamReader sr = new StreamReader(s))
{
buffer = await sr.ReadToEndAsync();
}
}
// return the buffer
return buffer;
}
// write the string buffer to a specific file
private async Task<bool> WriteBufferToFile(string fileName, string buffer)
{
try
{
StorageFolder local = Windows.Storage.ApplicationData.Current.LocalFolder; // local folder
var folder = await local.GetFolderAsync("DataFolder"); // sub folder
// open the file for writing
using (Stream s = await folder.OpenStreamForWriteAsync(fileName, CreationCollisionOption.ReplaceExisting))
{
using (StreamWriter sw = new StreamWriter(s))
{
await sw.WriteAsync(buffer);
}
}
}
catch (Exception ex)
{
string error_message = ex.Message;
return false;
}
return true;
}
// New Delete Lines function based off your old one
private string DeleteLines(string input_buffer, int id)
{
string output_buffer = "";
using (StringReader sr = new StringReader(input_buffer))
{
while (true)
{
string line = sr.ReadLine();
if (line != null)
{
if (String.Compare(line, id.ToString()) == 0)
{
}
else
{
// add it to the output_buffer plus the newline
output_buffer += (line + "\n");
}
}
else
{
break;
}
}
}
return output_buffer;
}
If you have trouble understanding a problem it generally a good idea to break it into smaller parts and debug from there.

Windows phone 8 append line to file

I have such strange problem with append line ... I'm quite new with developing for Windows phone, but I program¨m in c sharp for some time. So I tried to create file for saving users data (simple lines in txt file). I use this codes:
byte[] filebytes = System.Text.Encoding.UTF8.GetBytes("blablablabla");
StorageFolder local = Windows.Storage.ApplicationData.Current.LocalFolder;
var folder = await local.CreateFolderAsync("Data", CreationCollisionOption.OpenIfExists);
var file = await folder.CreateFileAsync("data.txt", CreationCollisionOption.OpenIfExists);
using (var s = await file.OpenStreamForWriteAsync())
{
s.Write(filebytes, 0, filebytes.Length);
}
for writing to file and
StorageFolder local = Windows.Storage.ApplicationData.Current.LocalFolder;
if (local != null)
{
var folder = await local.GetFolderAsync("Data");
var file = await folder.OpenStreamForReadAsync("data.txt");
using (StreamReader sr = new StreamReader(file))
{
string line;
while ((line = sr.ReadLine()) != null)
{
TextBlock.Text = line;
}
}
}
to read from it. I also tried many others possibility how to read/write to files, but all ended with the same result - all data lost, and in file was only last line. First I thought that problem will be in offset here s.Write(filebytes, 0, filebytes.Length); but in other methods it was in other way and nothing helped. Right now I have improved code, that it works, but read all data and write it all at once is not solution. Thanks for any advice.
Replace
s.Write(filebytes, 0, filebytes.Length);
With
await writer.WriteLineAsync("new entry");

How to clear a file before writing into it

I am using this code to write into my file:
private async void play_Click(object sender, RoutedEventArgs e)
{
String MyScore;
Double previousScore = 0;
StorageFolder local = Windows.Storage.ApplicationData.Current.LocalFolder;
var dataFolder1 = await local.CreateFolderAsync("MyFolder", CreationCollisionOption.OpenIfExists);
var file1 = await dataFolder1.CreateFileAsync("MyFile.txt", CreationCollisionOption.OpenIfExists);
var file = await dataFolder1.OpenStreamForReadAsync("MyFile.txt");
using (StreamReader streamReader = new StreamReader(file))
{
MyScore = streamReader.ReadToEnd();
}
if (MyScore != null && !MyScore.Equals(""))
{
previousScore = Convert.ToDouble(MyScore);
}
Double CurerentScore = 0;
Double Total = 0;
String scoreText = this.ScoreTB.Text;
CurerentScore = Convert.ToDouble(scoreText);
Total = previousScore - CurerentScore;
using (var s = await file1.OpenStreamForWriteAsync())
{
byte[] fileBytes = System.Text.Encoding.UTF8.GetBytes(Convert.ToString(Total));
s.Write(fileBytes, 0, fileBytes.Length);
}
}
But before writing into it, I want that my file should get cleared. What should I do?
This is what i have tried so far but the problem is that it writes the file up to the filebytes.length and due to that if the new information to be writed in file is less in terms of length in comparison to the privous length then some garbage value or unnecessay thing comes after the end of the new file
You can use this snippet :
var folder = ApplicationData.Current.LocalFolder;
// You are going to replace the file
var file = await folder.CreateFileAsync(fileName, CreationCollisionOption.ReplaceExisting);
using (var stream = await file.OpenStreamForWriteAsync())
{
var content = System.Text.Encoding.UTF8.GetBytes(Convert.ToString(Total));
await stream.WriteAsync(content, 0, content.Length);
}
To quote the documentation :
ReplaceExisting : Create the new file or folder with the desired name,
and replaces any file or folder that already exists with that name.
I have clear the file by writing a empty string to it and then i have written what i wanted in my file This solved my issue as nothing was there in the file so whatever i wanted to write to it came up successfully.
Simply use Stream.SetLength like this:
using (var s = await file1.OpenStreamForWriteAsync())
{
// Add this line
s.SetLength(0);
// Then write new bytes. use 's.SetLength(fileBytes.Length)' if needed.
byte[] fileBytes = System.Text.Encoding.UTF8.GetBytes(Convert.ToString(Total));
s.Write(fileBytes, 0, fileBytes.Length);
}

Categories

Resources