Load binary files with DataReader in windows 8 - c#

I'm trying to convert an old game of mine to windows 8 and I'm having a lot of trouble with my file loading. I'm trying a simple test with DataReader but I don't get the correct values.
First I write like this:
StorageFolder folder = ApplicationData.Current.LocalFolder;
StorageFile file = await folder.CreateFileAsync("file.dat",CreationCollisionOption.ReplaceExisting);
using (IRandomAccessStream fileStream = await file.OpenAsync(FileAccessMode.ReadWrite))
{
using (IOutputStream outputStream = fileStream.GetOutputStreamAt(0))
{
using (DataWriter writer = new DataWriter(outputStream))
{
try
{
writer.UnicodeEncoding = UnicodeEncoding.Utf8;
writer.ByteOrder = ByteOrder.LittleEndian;
writer.WriteInt32(1);
writer.WriteInt32(2);
await writer.StoreAsync();
writer.DetachStream();
}
catch (IOException)
{
}
}
}
}
Then I read
StorageFolder folder = ApplicationData.Current.LocalFolder;
StorageFile file = await folder.GetFileAsync("file.dat");
using (var fileStream = await file.OpenReadAsync())
{
using (IInputStream inputStream = fileStream.GetInputStreamAt(0))
{
using (DataReader reader = new DataReader(inputStream))
{
reader.UnicodeEncoding = UnicodeEncoding.Utf8;
reader.ByteOrder = ByteOrder.LittleEndian;
await reader.LoadAsync((uint)fileStream.Size);
var number = reader.ReadInt32();
var number2 = reader.ReadInt32();
reader.DetachStream();
}
}
}
But I don't get 1 and 2 when I read, just two really big numbers. So, something I missed this is now how you do it? I'm also trying to figure out the best way to work with strings, am I suppose to also write the byte length now as it ask for a "codeUnitCount" when I read?
It just seems like everything is a step back from the old binary reader.

Related

Windows Phone 8.1 Writing to File Not Working

I am writing text to a file in Windows Phone 8.1 like this:
private static async Task WriteData(String fileName, String content)
{
Byte[] data = Encoding.Unicode.GetBytes(content);
var folder = ApplicationData.Current.LocalFolder;
var file = await folder.CreateFileAsync(fileName, CreationCollisionOption.ReplaceExisting);
using (var s = await file.OpenStreamForWriteAsync())
{
await s.WriteAsync(data, 0, data.Length);
}
}
But when I read the file, it comes back empty. I have verified that there isn't some other method overwriting it by reading from the file immediately after I write to it. Am I missing something obvious here?
Maybe you can try:
public async Task SaveStreamToFile(Stream streamToSave, string fileName, CancellationToken cancelToken)
{
Byte[] buf= Encoding.Unicode.GetBytes(content);
var folder = ApplicationData.Current.LocalFolder;
StorageFile file = await folder.CreateFileAsync(fileName, CreationCollisionOption.ReplaceExisting);
using (Stream fileStram = await file.OpenStreamForWriteAsync())
{
int bytesread = 0;
while ((bytesread = await streamToSave.ReadAsync(buf, 0, BUFFER_SIZE)) > 0)
{
await fileStram.WriteAsync(buf, 0, bytesread);
cancelToken.ThrowIfCancellationRequested();
}
}
}
I was having the same problem. I save 2 files, one with debug information, and one with application specific information (a list of routes).The debug information seems to work OK
StorageFolder local = ApplicationData.Current.LocalFolder;
var file = await local.CreateFileAsync "debug.txt",CreationCollisionOption.ReplaceExisting);
await FileIO.WriteTextAsync(file, sbDebugInformation.ToString());
but the CreateCollisionOption.ReplaceExisting seemed to be causing problems with the other information, and I ended up with this, after many alternate attempts
StorageFolder local = ApplicationData.Current.LocalFolder;
var json = new DataContractJsonSerializer(typeof(RouteList));
var file = await local.CreateFileAsync(filename,CreationCollisionOption.OpenIfExists);
MemoryStream stream = new MemoryStream();
json.WriteObject(stream, routes);
await FileIO.WriteBytesAsync(file, stream.ToArray());

WriteAsync with DataReader how to stop reading

I have to upload a mp4 (Windows Phone 8.1 App C#) to a ftp and it works actually with the following code... but even after days of try'n'error I just don't know how write a condition for the end of the while. I can get the size of the file but don't know how to check for written bytes? Please help me
using (var stream2 = await ftpClient.OpenWriteAsync(PathToSet + FileName + ".mp4"))
{
using (var readStream = await videofile.OpenReadAsync())
{
IBuffer buffer = await FileIO.ReadBufferAsync(videofile);
DataReader reader = DataReader.FromBuffer(buffer);
byte[] fileContent = new byte[reader.UnconsumedBufferLength];
//int FileSize = Convert.ToInt32(reader.UnconsumedBufferLength);
while (true)
{
fileContent = new byte[reader.UnconsumedBufferLength];
reader.ReadBytes(fileContent);
await stream2.WriteAsync(fileContent.AsBuffer());
if(???) break;
}
await stream2.FlushAsync();
}
}
Check whether UnconsumedBufferLength is zero.

Windows Store App how to delete text from file

In a windows store app, how can I delete text from a file ? For example
If I have
StorageFile file = await roamingfolder.CreateFileAsync(filename,
CreationCollisionOption.OpenIfExists);
await FileIO.AppendTextAsync(file, temp);
How can i remove some text from this file ?
You generally read the text into a string, remove the text, and rewrite the file.
Here I get a file then I put the content to a stringbuilder then do some string operations, finally put the string back to the file using DataWriter
public static async Task UpdateTextContent(string contentItemId)
{
var storageFolder = await ApplicationData.Current.LocalFolder.GetFolderAsync(TARGET_FOLDER);
StorageFile sf = null;
try
{
//get content of the file make sure that it exist
sf = await storageFolder.GetFileAsync(TARGET_FILE);
}
catch (Exception ex)
{
}
if (sf != null)
{
var targettxtfile = await Windows.Storage.FileIO.ReadTextAsync(sf);
var sbProcessedTextToWrite = new StringBuilder(targettxtfile);
if (targettxtfile.IndexOf(contentItemId) >= 0)
{
string startmarker = new StringBuilder("[").Append(contentItemId).Append("#start]").ToString();
string endmarker = new StringBuilder("[").Append(contentItemId).Append("#end]").ToString();
int start = sbProcessedTextToWrite.ToString().IndexOf(startmarker);
int end = sbProcessedTextToWrite.ToString().IndexOf(endmarker);
int slen = end + endmarker.Length - start;
//compute position to remove
sbProcessedTextToWrite.Remove(start, slen);
}
using (IRandomAccessStream fileStream = await sf.OpenAsync(FileAccessMode.ReadWrite))
{
using (IOutputStream outputStream = fileStream.GetOutputStreamAt(0))
{
using (DataWriter dataWriter = new DataWriter(outputStream))
{
dataWriter.WriteString(sbProcessedTextToWrite.ToString());
await dataWriter.StoreAsync();
// For the in-memory stream implementation we are using, the flushAsync call
// is superfluous,but other types of streams may require it.
await dataWriter.FlushAsync();
// In order to prolong the lifetime of the stream, detach it from the
// DataWriter so that it will not be closed when Dispose() is called on
// dataWriter. Were we to fail to detach the stream, the call to
// dataWriter.Dispose() would close the underlying stream, preventing
// its subsequent use by the DataReader below.
dataWriter.DetachStream();
}
//same here flush the outputStream as well
await outputStream.FlushAsync();
}
}
}
}
Some references for this code

Save contact thumbnail on file

I would like save a profile picture in a file on localstorage.
With this code retrieval IRandomAccessStreamWithContentType but I don't understand how to save it on disk.
var contactPicker = new Windows.ApplicationModel.Contacts.ContactPicker();
contactPicker.CommitButtonText = "Select";
var contact = await contactPicker.PickSingleContactAsync();
using (IRandomAccessStreamWithContentType stream = await contact.GetThumbnailAsync())
{
//Save stream on LocalFolder
}
Assuming IRandomAccessStreamWithContentType works like any other stream, this should do the trick:
using (IRandomAccessStreamWithContentType stream = await contact.GetThumbnailAsync())
{
using(FileStream fs = new FileStream("path", FileMode.CreateNew))
{
stream.CopyTo(fs);
}
}

How write a file using StreamWriter in Windows 8?

I'm having trouble when creating a StreamWriter object in windows-8, usually I just create an instance just passing a string as a parameter, but in Windows 8 I get an error that indicates that it should recieve a Stream, but I noticed that Stream is an abstract class, Does anybody knows how will be the code to write an xml file?, BTW I'm using .xml because I want to save the serialized object, or does anyone knows how to save to a file a serialized object in Windows 8?.
Any ideas?
Currently using Windows 8 Consumer Preview
Code:
StreamWriter sw = new StreamWriter("person.xml");
Error:
The best overloaded method match for 'System.IO.StreamWriter.StreamWriter(System.IO.Stream)' has some invalid arguments
Instead of StreamWriter you would use something like this:
StorageFolder folder = ApplicationData.Current.LocalFolder;
StorageFile file = await folder.CreateFileAsync();
using (IRandomAccessStream fileStream = await file.OpenAsync(FileAccessMode.ReadWrite))
{
using (IOutputStream outputStream = fileStream.GetOutputStreamAt(0))
{
using (DataWriter dataWriter = new DataWriter(outputStream))
{
//TODO: Replace "Bytes" with the type you want to write.
dataWriter.WriteBytes(bytes);
await dataWriter.StoreAsync();
dataWriter.DetachStream();
}
await outputStream.FlushAsync();
}
}
You can look at the StringIOExtensions class in the WinRTXamlToolkit library for sample use.
EDIT*
While all the above should work - they were written before the FileIO class became available in WinRT, which simplifies most of the common scenarios that the above solution solves since you can now just call await FileIO.WriteTextAsync(file, contents) to write text into file and there are also similar methods to read, write or append strings, bytes, lists of strings or IBuffers.
You can create a common static method which you can use through out application like this
private async Task<T> ReadXml<T>(StorageFile xmldata)
{
XmlSerializer xmlser = new XmlSerializer(typeof(List<myclass>));
T data;
using (var strm = await xmldata.OpenStreamForReadAsync())
{
TextReader Reader = new StreamReader(strm);
data = (T)xmlser.Deserialize(Reader);
}
return data;
}
private async Task writeXml<T>(T Data, StorageFile file)
{
try
{
StringWriter sw = new StringWriter();
XmlSerializer xmlser = new XmlSerializer(typeof(T));
xmlser.Serialize(sw, Data);
using (IRandomAccessStream fileStream = await file.OpenAsync(FileAccessMode.ReadWrite))
{
using (IOutputStream outputStream = fileStream.GetOutputStreamAt(0))
{
using (DataWriter dataWriter = new DataWriter(outputStream))
{
dataWriter.WriteString(sw.ToString());
await dataWriter.StoreAsync();
dataWriter.DetachStream();
}
await outputStream.FlushAsync();
}
}
}
catch (Exception e)
{
throw new NotImplementedException(e.Message.ToString());
}
}
to write xml simply use
StorageFile file = await ApplicationData.Current.LocalFolder.CreateFileAsync("data.xml",CreationCollisionOption.ReplaceExisting);
await writeXml(Data,file);
and to read xml use
StorageFile file = await ApplicationData.Current.LocalFolder.GetFileAsync("data.xml");
Data = await ReadXml<List<myclass>>(file);

Categories