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.
Related
I have a text file consisting of 21000 lines, i have an attribute and i need to search it in the .txt file and need to return a value from the same too. All code is done and tried async plus new thread but there is a five second lag during the button click . how can i remove the lag.
Tried on new unity and C#
public async void read()
{
string[] lines = await ReadAllLinesAsync("Assets/Blockchain Module/" + File + ".csv");
fields = null;
for (int j = 0; j < lines.Length; j++)
{
fields = lines[j].Split(',');
x[j] = System.Convert.ToDouble(fields[1]);
y[j] = System.Convert.ToDouble(fields[2]);
z[j] = System.Convert.ToDouble(fields[3]);
temp[j] = System.Convert.ToDouble(fields[4]);
}
}
public void Start()
{
Thread thread = new Thread(read);
thread.Start();
//gradient.Evaluate()
//var main = particleSystem.main;
//main.maxParticles = 200;
}
private const FileOptions DefaultOptions = FileOptions.Asynchronous | FileOptions.SequentialScan;
public static Task<string[]> ReadAllLinesAsync(string path) => ReadAllLinesAsync(path, Encoding.UTF8);
public static async Task<string[]> ReadAllLinesAsync(string path, Encoding encoding)
{
var lines = new List<string>();
// Open the FileStream with the same FileMode, FileAccess
// and FileShare as a call to File.OpenText would've done.
using (var stream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, DefaultBufferSize, DefaultOptions))
using (var reader = new StreamReader(stream, encoding))
{
string line;
while ((line = await reader.ReadLineAsync()) != null)
{
lines.Add(line);
}
}
return lines.ToArray();
}
Reading and parsing the file apparently costs 5 seconds on your system. I don't think reading it line by line is the fastest approach, but anyway, don't parse the file for each request.
Read it once on application startup, and cache it in an appropriate data type.
In general if your search is line based is better to read line one by one instead to read all the file:
using (StreamReader reader = new StreamReader("filename"))
{
while (true)
{
string line = await reader.ReadLineAsync();
if (line == null)
{
break;
}
//logic here...
}
}
I have a test.zip file which contains inside a Folder with a bunch of other files and folders in it.
I found SharpZipLib after figuring out that .gz / GzipStream was not the way to go since its only for individual files. More importantly, doing this is similar to using GZipStream meaning it will create a FILE. But I have whole folder zipped. How do I unzip to a
For some reason the example unzipping here is set to ignore directories, so I'm not totally sure how that is done.
Also, I need to use .NET 2.0 for accomplish this.
I think it is the easier way.
Default functionality (please look here for more info https://github.com/icsharpcode/SharpZipLib/wiki/FastZip)
it extract with folders.
code:
using System;
using ICSharpCode.SharpZipLib.Zip;
var zipFileName = #"T:\Temp\Libs\SharpZipLib_0860_Bin.zip";
var targetDir = #"T:\Temp\Libs\unpack";
FastZip fastZip = new FastZip();
string fileFilter = null;
// Will always overwrite if target filenames already exist
fastZip.ExtractZip(zipFileName, targetDir, fileFilter);
This is how I did it:
public void UnZipp(string srcDirPath, string destDirPath)
{
ZipInputStream zipIn = null;
FileStream streamWriter = null;
try
{
Directory.CreateDirectory(Path.GetDirectoryName(destDirPath));
zipIn = new ZipInputStream(File.OpenRead(srcDirPath));
ZipEntry entry;
while ((entry = zipIn.GetNextEntry()) != null)
{
string dirPath = Path.GetDirectoryName(destDirPath + entry.Name);
if (!Directory.Exists(dirPath))
{
Directory.CreateDirectory(dirPath);
}
if (!entry.IsDirectory)
{
streamWriter = File.Create(destDirPath + entry.Name);
int size = 2048;
byte[] buffer = new byte[size];
while ((size = zipIn.Read(buffer, 0, buffer.Length)) > 0)
{
streamWriter.Write(buffer, 0, size);
}
}
streamWriter.Close();
}
}
catch (System.Threading.ThreadAbortException lException)
{
// do nothing
}
catch (Exception ex)
{
throw (ex);
}
finally
{
if (zipIn != null)
{
zipIn.Close();
}
if (streamWriter != null)
{
streamWriter.Close();
}
}
}
It's sloppy but I hope it helps!
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);
}
Hi i'm stucked in a problem, i created a txt file that i put on the app. I'm trying to read from it the content that i write on it before. With that code:
public async Task WriteDataToFileAsync(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);
}
}
public async Task<string> ReadFileContentsAsync(string fileName)
{
var folder = ApplicationData.Current.LocalFolder;
try
{
var file = await folder.OpenStreamForReadAsync(fileName);
using (var streamReader = new StreamReader(file))
{
return streamReader.ReadToEnd();
}
}
catch (Exception)
{
MessageBox.Show("Error");
return string.Empty;
}
}
private async void functionWhereNeedReeding()
{
string contents = await this.ReadFileContentsAsync("myimportedfile.txt");
MessageBox.Show(contents);
}
Give me all times the message of error and i can't understand where is my mistake. Hoping that you'll help me. For sure contents is still empty.
I created a helper function in my WP 7 project recently, to read a text file included in the project. You can try to use it, the function also working in WP 8 project :
public static class FileHelper
{
public static string ReadFile(string filePath)
{
var ResrouceStream = Application.GetResourceStream(new Uri(filePath, UriKind.Relative));
if (ResrouceStream != null)
{
Stream myFileStream = ResrouceStream.Stream;
if (myFileStream.CanRead)
{
StreamReader myStreamReader = new StreamReader(myFileStream);
return myStreamReader.ReadToEnd();
}
}
return "";
}
}
Then I can use that function this way (in this example the file resides under Assets folder) :
var textFileContent = FileHelper.ReadFile(#"Assets\MyTextFile.txt");
I am using the SharpZipLib open source .net library from www.icsharpcode.net
My goal is to unzip an xml file and read it into a dataset. However I get the following error reading the file into a dataset: "Data at the root level is invalid. Line 1, position 1."
I believe what is happening is the unzipping code is not releasing the file for the following reasons.
1.) If I unzip the file and exit the application. When I restart the app I CAN read the unzipped file into a dataset.
2.) If I read in the xml file right after writing it out (no zipping) then it works fine.
3.) If I write the dataset to xml, zip it up, unzip it, then attempt to read it back in I get the exception.
The code below is pretty straight forward. UnZipFile will return the name of the file just unzipped. Right below this call is the call to read it into a dataset. The variable fileToRead is the full path to the newly unzipped xml file.
string fileToRead = UnZipFile(filepath, DOViewerUploadStoreArea);
ds.ReadXml(fileToRead )
private string UnZipFile(string file, string dirToUnzipTo)
{
string unzippedfile = "";
try
{
ZipInputStream s = new ZipInputStream(File.OpenRead(file));
ZipEntry myEntry;
string tmpEntry = String.Empty;
while ((myEntry = s.GetNextEntry()) != null)
{
string directoryName = dirToUnzipTo;
string fileName = Path.GetFileName(myEntry.Name);
string fileWDir = directoryName + fileName;
unzippedfile = fileWDir;
FileStream streamWriter = File.Create(fileWDir);
int size = 4096;
byte[] data = new byte[4096];
while (true)
{
size = s.Read(data, 0, data.Length);
if (size > 0) { streamWriter.Write(data, 0, size); }
else { break; }
}
streamWriter.Close();
}
s.Close();
}
catch (Exception ex)
{
LogStatus.WriteErrorLog(ex, "ERROR", "DOViewer.UnZipFile");
}
return (unzippedfile);
}
Well, what does the final file look like? (compared to the original). You don't show the zipping code, which might be part of the puzzle, especially as you are partially swallowing the exception.
I would also try ensuring everything IDisposable is Dispose()d, ideally via using; also - in case the problem is with path construction, use Path.Combine. And note that if myEntry.Name contains sub-directories, you will need to create them manually.
Here's what I have - it works for unzipping ICSharpCode.SharpZipLib.dll:
private string UnZipFile(string file, string dirToUnzipTo)
{
string unzippedfile = "";
try
{
using(Stream inStream = File.OpenRead(file))
using (ZipInputStream s = new ZipInputStream(inStream))
{
ZipEntry myEntry;
byte[] data = new byte[4096];
while ((myEntry = s.GetNextEntry()) != null)
{
string fileWDir = Path.Combine(dirToUnzipTo, myEntry.Name);
string dir = Path.GetDirectoryName(fileWDir);
// note only supports a single level of sub-directories...
if (!Directory.Exists(dir)) Directory.CreateDirectory(dir);
unzippedfile = fileWDir; // note; returns last file if multiple
using (FileStream outStream = File.Create(fileWDir))
{
int size;
while ((size = s.Read(data, 0, data.Length)) > 0)
{
outStream.Write(data, 0, size);
}
outStream.Close();
}
}
s.Close();
}
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
return (unzippedfile);
}
It could also be that the problem is either in the code that writes the zip, or the code that reads the generated file.
I compared the original with the final using TextPad and they are identical.
Also I rewrote the code to take advantage of the using. Here is the code.
My issue seems to be centered around file locking or something. If I unzip the file quit the application then start it up it will read find.
private string UnZipFile(string file, string dirToUnzipTo)
{
string unzippedfile = "";
try
{
using (ZipInputStream s = new ZipInputStream(File.OpenRead(file)))
{
ZipEntry theEntry;
while ((theEntry = s.GetNextEntry()) != null)
{
string directoryName = dirToUnzipTo;
string fileName = Path.GetFileName(theEntry.Name);
string fileWDir = directoryName + fileName;
unzippedfile = fileWDir;
if (fileName != String.Empty)
{
using (FileStream streamWriter = File.Create(fileWDir))
{
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 ex)
{
LogStatus.WriteErrorLog(ex, "ERROR", "DOViewer.UnZipFile");
}
return (unzippedfile);
}
This is a lot simpler to do with DotNetZip.
using (ZipFile zip = ZipFile.Read(ExistingZipFile))
{
zip.ExtractAll(TargetDirectory);
}
If you want to decide on which files to extract ....
using (ZipFile zip = ZipFile.Read(ExistingZipFile))
{
foreach (ZipEntry e in zip)
{
if (wantThisFile(e.FileName)) e.Extract(TargetDirectory);
}
}
If you would like to overwrite existing files during extraction:
using (ZipFile zip = ZipFile.Read(ExistingZipFile))
{
zip.ExtractAll(TargetDirectory, ExtractExistingFileAction.OverwriteSilently);
}
Or, to extract password-protected entries:
using (ZipFile zip = ZipFile.Read(ExistingZipFile))
{
zip.Password = "Shhhh, Very Secret!";
zip.ExtractAll(TargetDirectory, ExtractExistingFileAction.OverwriteSilently);
}