I am reading data from IsolatedStorage, but can't edit it in ScheduledTask. How can I edit it?
private void StartToastTask(ScheduledTask task)
{
long rank = 0, difference = 0;
string text = "", nickname = "";
PishtiWCF.PishtiWCFServiceClient ws = ServiceClass.GetPishtiWCFSvc();
ws.GetUsersRankCompleted += (src, e) =>
{
try
{
if (e.Error == null)
{
difference = rank - e.Result.GeneralRank;
if (!String.IsNullOrEmpty(nickname))
{
if (difference < 0)
text = string.Format("{0}, {1} kişi seni geçti!", nickname, difference.ToString(), e.Result.GeneralRank);
else if (difference > 0)
text = string.Format("{0}, {1} kişiyi daha geçtin!", nickname, Math.Abs(difference).ToString(), e.Result.GeneralRank);
else if (e.Result.GeneralRank != 1)
text = string.Format("{0}, sıralamadaki yerin değişmedi!", nickname, e.Result.GeneralRank);
else
text = string.Format("{0}, en büyük sensin, böyle devam!", nickname);
}
else
return;
Mutex mut;
if (!Mutex.TryOpenExisting("IsoStorageMutex", out mut))
mut = new Mutex(false, "IsoStorageMutex");
mut.WaitOne();
using (IsolatedStorageFile file = IsolatedStorageFile.GetUserStoreForApplication())
{
using (IsolatedStorageFileStream stream = file.OpenFile("UserRanks", FileMode.Open, FileAccess.Write))
{
StreamWriter writer = new StreamWriter(stream);
writer.Write(string.Format("{0},{1}", nickname, e.Result.GeneralRank));
writer.Close();
stream.Close();
}
}
mut.ReleaseMutex();
ShellToast toast = new ShellToast();
toast.Title = "Pishti";
toast.Content = text;
toast.Show();
}
FinishTask(task);
}
catch (Exception)
{
}
};
try
{
Mutex mut;
if (!Mutex.TryOpenExisting("IsoStorageMutex", out mut))
mut = new Mutex(false, "IsoStorageMutex");
mut.WaitOne();
using (IsolatedStorageFile file = IsolatedStorageFile.GetUserStoreForApplication())
{
using (IsolatedStorageFileStream stream = file.OpenFile("UserRanks", FileMode.Open, FileAccess.Read))
{
using (StreamReader reader = new StreamReader(stream))
{
string temp = reader.ReadToEnd();
if (temp.Split(',').Count() > 1)
{
nickname = temp.Split(',')[0];
rank = long.Parse(temp.Split(',')[1]);
ws.GetUsersRankAsync(nickname);
}
reader.Close();
}
stream.Close();
}
}
mut.ReleaseMutex();
}
catch (Exception)
{
}
}
I am getting rank from UserRanks file, for example 1200, but when I get and data from WCF, edit it to 1000 and want to write it to IsolatedStorage, It doesn't crash application but it fails.
Do you know why?
Thanks.
I've fixed it with delete file.
Mutex mut;
if (!Mutex.TryOpenExisting("IsoStorageMutex", out mut))
mut = new Mutex(false, "IsoStorageMutex");
mut.WaitOne();
using (IsolatedStorageFile file = IsolatedStorageFile.GetUserStoreForApplication())
{
if (file.FileExists("UserRanks"))
file.DeleteFile("UserRanks");
using (IsolatedStorageFileStream stream = file.OpenFile("UserRanks", FileMode.OpenOrCreate, FileAccess.Write))
{
StreamWriter writer = new StreamWriter(stream);
writer.Write(string.Format("{0},{1}", nickname, e.Result.GeneralRank));
writer.Close();
stream.Close();
}
}
mut.ReleaseMutex();
You appear to write to the file first, which makes sense, but when you do so you use a file access mode - FileMode.Open - which means "open an existing file". The first time you do this the file won't exist and the open will fail.
You should either use FileMode.OpenOrCreate, which is self explanatory, or FileMode.Append which will open the file if it exists and seek to the end of the file, or create a new file if it doesn't.
If you want to throw away any pre-existing file (which is what your delete then create will do) then just use FileMode.Create
Related
hi I am working on a xamarin.forms app, While trying to open one of the csv file the following exception is displayed "input string is not in a correct format " the csv file contains a field called item name which consists the following names ET Door,E459-2,H 91 Ft and Key,Door so these both items contain comma so I am not able to open the csv file which consists of these two elements as they contain special characters like comma and underscore .Here is my code to read and open csv file ,please check the code and let me know what changes do i need to make so the file with items consisting of special characters also open ?
public async void OnProcess(object o, EventArgs args)
{
if (!string.IsNullOrWhiteSpace(csv_file.Text))
{
// _database.AddFiles();
if (App.Current.MainPage is NavigationPage)
{
try
{
List<ItemsCSV> items = new List<ItemsCSV>();
string[] lines = File.ReadAllLines(string.Format(#"{0}", this.file.FilePath));
if (lines != null)
{
for (int x = 1; x < lines.Length; x++)
{
string data = lines[x];
string[] item = data.Split(',');
// ItemsCSV itemsCSV = new ItemsCSV();
_itemsCSV = new ItemsCSV();
{
_itemsCSV.Cycle_Count = string.IsNullOrEmpty(item.ElementAtOrDefault(0)) ? 0 : Convert.ToInt32(item[0]);
_itemsCSV.Line_Number = string.IsNullOrEmpty(item.ElementAtOrDefault(1)) ? 0 : Convert.ToInt32(item[1]);
_itemsCSV.Item_Number = item.ElementAtOrDefault(2);
_itemsCSV.Name = item.ElementAtOrDefault(3);
_itemsCSV.Warehouse = item.ElementAtOrDefault(4);
_itemsCSV.Aisle = item.ElementAtOrDefault(5);
_itemsCSV.Bin = item.ElementAtOrDefault(6);
_itemsCSV.Level = item.ElementAtOrDefault(7);
_itemsCSV.Order_Qty = string.IsNullOrEmpty(item.ElementAtOrDefault(8)) ? 0 : Convert.ToInt32(item[8]);
_itemsCSV.Order_UOM = item.ElementAtOrDefault(9);
_itemsCSV.Consumption_Qty = string.IsNullOrEmpty(item.ElementAtOrDefault(10)) ? 0 : Convert.ToInt32(item[10]);
_itemsCSV.Consumption_UOM = item.ElementAtOrDefault(11);
_itemsCSV.Status = "";
};
items.Add(_itemsCSV);
_database.AddItems(_itemsCSV);
}
var result = await DisplayAlert("", "CSV has been processed, please do cycle count", "OK", "Cancel");
if(result == true)
{
var cyclecountPage = new CycleCountPage(items, 0, "MainPage",this.file.FilePath);
await (App.Current.MainPage as NavigationPage).PushAsync(cyclecountPage);
}
else
{
}
}
else
{
await DisplayAlert("Alert", "File is empty", "OK");
}
}
catch (Exception e)
{
await DisplayAlert("Exception", e.Message, "OK");
}
}
}
else
{
await DisplayAlert("Alert", "File name is mandatory", "OK");
}
}
I want to read file using StreamResourceInfo GetResourceStream(Uri uriResource) method where my filename is Assets and its type if file (extension) so I used following line of code in windows phone 8.1 sdk,
StreamResourceInfo info = App.GetResourceStream(new Uri("Assets", UriKind.Relative));
But the info variable shows null value.
Is it necessary to use GetResourceStream in your case? Your question is a little bit unclear, but if you want to get the content of the file you can try this:
public async Task<string> GetFileContent(string fileName)
{
try
{
string text = string.Empty;
StorageFile storageFile = await Windows.ApplicationModel.Package.Current.InstalledLocation.GetFileAsync(fileName);
if (storageFile != null)
{
IBuffer buffer = await FileIO.ReadBufferAsync(storageFile);
DataReader reader = DataReader.FromBuffer(buffer);
byte[] fileContent = new byte[reader.UnconsumedBufferLength];
reader.ReadBytes(fileContent);
text = Encoding.UTF8.GetString(fileContent, 0, fileContent.Length);
}
return text;
}
catch (Exception e)
{
return string.Empty;
}
}
Note, it returns string UTF8 encoded, you can change it if necessary.
usage:
var fileContent = await GetFileContent(#"Assets\[yourfile]");
I am building a WP8 app that downloads images using HttpClient in a background task. My problem is that some images are not downloaded no matter how much time I wait for them to finish. The image sizes are a few megabytes at maximum.
The code I use to download images:
internal static async Task<bool> Download_Wallpaper(string image_url, string file_name, string destination_folder_name)
{
try
{
using (var client = new HttpClient())
{
// 12MB max images
client.Timeout = TimeSpan.FromSeconds(5);
client.MaxResponseContentBufferSize = DeviceStatus.ApplicationMemoryUsageLimit / 2;
//client.Timeout = TimeSpan.FromSeconds(5);
byte[] image_byte_arr;
try
{
/* var requestMessage = new HttpRequestMessage( HttpMethod.Get, image_url );
var responseMessage = await client.SendAsync((requestMessage));
// byte array of image
image_byte_arr = await responseMessage.Content.ReadAsByteArrayAsync();
*/
// byte array of image
image_byte_arr = await client.GetByteArrayAsync(image_url);
}
// Could not download
catch (OutOfMemoryException X)
{
GC.Collect();
return false;
}
var folder = await StorageFolder.GetFolderFromPathAsync(destination_folder_name);
// Create file
StorageFile file = await folder.CreateFileAsync(file_name, CreationCollisionOption.ReplaceExisting);
using (var write_stream = await file.OpenStreamForWriteAsync())
{
write_stream.Write(image_byte_arr, 0, image_byte_arr.Length);
}
Console.WriteLine(DeviceStatus.ApplicationCurrentMemoryUsage);
return true;
}
}
catch (HttpRequestException X)
{
Console.WriteLine(X);
return false;
}
catch (OutOfMemoryException X)
{
GC.Collect();
return false;
}
catch (Exception X)
{
Console.WriteLine(X);
return false;
}
}
This is an example image that fails to download: https://upload.wikimedia.org/wikipedia/commons/9/95/Tracy_Caldwell_Dyson_in_Cupola_ISS.jpg
In my experience all wikimedia images fail to download for some reason.
I see no way of tracking download progress using HttpClient. Is there a way to do so?
Edit: It seems that setting the timeout does not have any function. The HttpRequestException is not thrown after 5 seconds.
Edit2: I tried a different approach, the one that anonshankar suggested. With that method the code would get stuck at the line:
byte[] img = response.Content.ReadAsByteArrayAsync();
So the HttpResponse arrives, but somehow the bytes could not be read out, no matter how much time I gave it. How could this even happen? The hard part is getting the response, reading out the bytes should be simple.
Again, this only happens with some images, most of them downloads correctly. One example is mentioned above.
I have modified my image downloader code, so that it times out after a few seconds. Here is my final code:
internal static async Task<bool> Download_Wallpaper(string image_url, string file_name, string destination_folder_name)
{
try
{
using (var client = new HttpClient())
{
// prevent running out of memory
client.MaxResponseContentBufferSize = DeviceStatus.ApplicationMemoryUsageLimit / 3;
byte[] image_byte_arr = null;
using (CancellationTokenSource cts = new CancellationTokenSource())
{
var task = Task.Factory.StartNew(() =>
{
try
{
image_byte_arr = client.GetByteArrayAsync(image_url).Result;
}
catch (AggregateException X)// Handling read errors, usually image is too big
{
Console.WriteLine(X.Message);
foreach (var v in X.InnerExceptions)
Console.WriteLine(v.Message);
image_byte_arr = null;
}
}, cts.Token);
bool finished_in_time = task.Wait(TimeSpan.FromSeconds(5));
if (!finished_in_time)// Timeout
{
cts.Cancel();
task.Wait();
return false;
}
else if (image_byte_arr == null)// Read error
{
return false;
}
}
var folder = await StorageFolder.GetFolderFromPathAsync(destination_folder_name);
// Create file
StorageFile file = await folder.CreateFileAsync(file_name, CreationCollisionOption.ReplaceExisting);
using (var write_stream = await file.OpenStreamForWriteAsync())
{
write_stream.Write(image_byte_arr, 0, image_byte_arr.Length);
}
Console.WriteLine(DeviceStatus.ApplicationCurrentMemoryUsage);
return true;
}
}
catch (HttpRequestException X)
{
Console.WriteLine(X);
return false;
}
catch (OutOfMemoryException X)
{
GC.Collect();
return false;
}
catch (Exception X)
{
Console.WriteLine(X);
return false;
}
}
Any improvement suggestions are welcome, and I still don't understand why does the method HttpContent.ReadAsByteArrayAsync() gets stuck.
Just try out this snippet which worked for me.
HttpClient client = new HttpClient();
HttpResponseMessage response = await client.GetAsync("give the url");
byte[] img = response.Content.ReadAsByteArray();
InMemoryRandomAccessStream randomAccessStream = new InMemoryRandomAccessStream();
DataWriter writer = new DataWriter(randomAccessStream.GetOutputStreamAt(0));
writer.WriteBytes(img);
await writer.StoreAsync();
BitmapImage b = new BitmapImage();
b.SetSource(randomAccessStream);
pic.Source = b; //(pic is an `<Image>` defined in the `XAML`
Hope it helps!
I am trying to download and save Zip file from server.
I have string from server.
lastStatusCode = response.StatusCode;
using (StreamReader httpWebStreamReader = new StreamReader(response.GetResponseStream()))
{
string result = httpWebStreamReader.ReadToEnd();
RequestList[0].OnResponse(result, lastStatusCode);
}
if "lastStatusCode" is OK then i am making Zip file.
public async void saveFile(string response)
{
var fileBytes = System.Text.Encoding.UTF8.GetBytes(response.ToCharArray());
// Get the local folder.
StorageFolder local = Windows.Storage.ApplicationData.Current.LocalFolder;
// Create a new folder name MyFolder.
var dataFolder = await local.CreateFolderAsync("TestFolder",
CreationCollisionOption.OpenIfExists);
// Create a new file named DataFile.txt.
var file = await dataFolder.CreateFileAsync("File.zip",
CreationCollisionOption.ReplaceExisting);
// Write the data from the textbox.
using (var s = await file.OpenStreamForWriteAsync())
{
s.Write(fileBytes, 0, fileBytes.Length);
}
}
what I am doing wrong? I can't open this file.
I fixed that problem! Converting Stream to String and then String to Byte was bad idea.
I was converting Stream to byte:
lock (RequestList)
{
//WebRequest request = (WebRequest)callbackResult.AsyncState;
HttpWebRequest request = (HttpWebRequest)callbackResult.AsyncState;
try
{
HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(callbackResult);
Stream s = response.GetResponseStream();
lastStatusCode = response.StatusCode;
s.Position = 0;
// Now read s into a byte buffer with a little padding.
byte[] bytes = new byte[s.Length];
int numBytesToRead = (int)s.Length;
int numBytesRead = 0;
do
{
// Read may return anything from 0 to 10.
int n = s.Read(bytes, numBytesRead, numBytesToRead);
numBytesRead += n;
numBytesToRead -= n;
} while (numBytesToRead > 0);
s.Close();
WriteFile("Test.zip",bytes);
RequestList[0].OnResponse(bytes, lastStatusCode);
}
catch (WebException e)
{
Debug.WriteLine("Error : " + e.Message);
byte[] streamData = System.Text.Encoding.UTF8.GetBytes(e.Message);
RequestList[0].OnResponse(streamData, HttpStatusCode.InternalServerError);
}
}
I am making zip file here
public async void WriteFile(string fileName, byte[] response)
{
IStorageFolder applicationFolder = ApplicationData.Current.LocalFolder;
IStorageFile storageFile = await applicationFolder.CreateFileAsync(fileName, CreationCollisionOption.ReplaceExisting);
//var content = System.Text.Encoding.UTF8.GetBytes(response);
using (Stream stream = await storageFile.OpenStreamForWriteAsync())
{
await stream.WriteAsync(response, 0, response.Length);
}
}
Actually i am trying to saving a .zip/.epub file from webResponse into my wp8 isolated storage which contains saveral .html, .png, .jpg and .woff ( Web Open Font Format) files.
my following code is saving only .html and .png files from the .zip/.epub, when it try to save .jpg and .woff format files it shows following exception.
Exception: Operation not permitted on IsolatedStorageFileStream BinaryWritter
Please help me to solve that how to streamWrite myFont.woff file ?
my code is following.
private async void ReadWebRequestCallback(IAsyncResult ar)
{
IsolatedStorageFile myIsoStorage = IsolatedStorageFile.GetUserStoreForApplication();
string dir = "/mainDir/subDir/subtosubDir";
if (!myIsoStorage.DirectoryExists(dir))
{
myIsoStorage.CreateDirectory(dir);
}
HttpWebRequest myRequest = (HttpWebRequest)ar.AsyncState;
HttpWebResponse myResponse = (HttpWebResponse)myRequest.EndGetResponse(ar);
using (StreamReader httpwebStreamReader = new StreamReader(myResponse.GetResponseStream()))
{
using (ZipInputStream s = new ZipInputStream(httpwebStreamReader.BaseStream))
{
ZipEntry theEntry;
try
{
while ((theEntry = s.GetNextEntry()) != null)
{
if (theEntry.IsDirectory)
{
string strNewDirectory = dir+"/"+theEntry.Name;
if (!myIsoStorage.DirectoryExists(strNewDirectory))
{
myIsoStorage.CreateDirectory(strNewDirectory);
}
}
else if (theEntry.IsFile)
{
string fileName = dir + "/" + theEntry.Name;
//save file to isolated storage
using (BinaryWriter streamWriter = new BinaryWriter(new IsolatedStorageFileStream(fileName, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite, myIsoStorage)))
{
int size = 2048;
byte[] data = new byte[2048];
while (true)
{
size = s.Read(data, 0, data.Length);
if (size > 0)
{
streamWriter.Write(data, 0, size);
}
else
{
break;
}
}
}
}
}
}
catch (Exception ze)
{
Debug.WriteLine(ze.Message);
}
}
}
}
using (IsolatedStorageFileStream fileStream = isf.OpenFile(fullFilePath, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite))
{
s.CopyTo(fileStream);
}
In my case it is the only way to save different extension's files into the isolated Storage, BinaryWriter will not work. so #KooKiz was right.
Thanks Kookiz :)