I have a file which contains several text entries, say
one
two
three
Now, I need to delete one of the entries, say "two". I'm using StreamReader and StreamWriter classes. In order to delete, first, I read the contents of the file into a string using StreamReader class, replace the "two\r\n" in the read string with "" and then, I write this string to the file using the StreamWriter class. But, since the length of the newly written string i.e. "one\r\nthree\r\n" is less than the original string i.e. "one\r\ntwo\r\nthree\r\n", the first few characters get overwritten and the characters near the end still stay there giving rise to "one\r\nthree\r\nree\r\n". Seems like a simple problem but, it has me stuck. Any ideas?
The user variable contains the entry to be deleted.
string all = "";
using (IsolatedStorageFileStream isoStream = store.OpenFile("user_list", FileMode.Open))
{
using (StreamReader sr = new StreamReader(isoStream))
{
all = sr.ReadToEnd();
all = all.Replace(user + "\r\n", "");
}
}
using (IsolatedStorageFileStream isoStream = store.OpenFile("user_list", FileMode.Open))
{
using (StreamWriter sw = new StreamWriter(isoStream))
{
sw.Write(all);
sw.Flush();
}
}
You can fix the problem by changing FileMode.Open to FileMode.Create when you're opening the output file. That is:
using (IsolatedStorageFileStream isoStream =
store.OpenFile("user_list", FileMode.Create))
That will overwrite the previous file.
Related
i want clear text file contet with this method
private void writeTextFile(string filePath, string text)
{
if (!File.Exists(filePath))
{
File.Create(filePath).Close();
}
using (StreamWriter tw = new StreamWriter(filePath))
{
File.WriteAllText(filePath,"");
tw.WriteLine(text);
tw.Close();
}
}
but i get this error
The process cannot access the file because it is being used by another process.
but this not open in anywhere ,
please help me
thank's
That's because you're creating a StreamWriter, then using File.WriteAllText. Your File is already being accessed with the StreamWriter.
File.WriteAllText does just that, writes the entire string you pass to it to a file. StreamWriter is unnecessary if you're going to use File.WriterAllText.
If you don't care about overwriting an existing file, you can do this:
private void writeTextFile(string filePath, string text)
{
File.WriteAllText(filePath, text);
}
If you want to use StreamWriter (which, by the way, File.WriteAllText uses, it just hides it), and append to the file, you can do this (from this answer):
using(StreamWriter sw = File.AppendText(path))
{
tw.WriteLine(text);
}
You can use StreamWriter for creating a file for write and use Truncate to write with clearing previous content.
StreamWriter writeFile;
writeFile = new StreamWriter(new IsolatedStorageFileStream(filename, FileMode.Truncate, myIsolatedStorage));
writeFile.WriteLine("String");
writeFile.Close();
This use FileMode.Truncate
Truncate Specifies that an existing file it to be opened and then truncated so that its size is zero bytes.
Assuming that your file already exists and you want to clear its contents before populating it or whatever, I found the best way to do this with StreamWriter is..
// this line does not create test.txt file, assuming that it already exists, it will remove the contents of test.txt
Dim sw As System.IO.StreamWriter = New System.IO.StreamWriter(Path.GetFullPath(C:\test.txt), False)
// this line will now be inserted into your test.txt file
sw.Write("hey there!")
// I decided to use this solution
// this section is to clear MyFile.txt
using(StreamWriter sw = new StreamWriter(#"MyPath\MyFile.txt", false))
{
foreach(string line in listofnames)
{
sw.Write(""); // change WriteLine with Write
}
sw.Close();
}
// and this section is to copy file names to MyFile.txt
using(StreamWriter file = new StreamWriter(#"MyPath\MyFile.txt", true))
{
foreach(string line in listofnames)
{
file.WriteLine(line);
}
}
You only need to specify false in the second parameter of the constructor for StreamWriter( route, false )
String ruta = #"C:\Address\YourFile".txt";
using (StreamWriter file = new StreamWriter(ruta, false))
{
for ( int i = 0; i < settings.Length; ++i )
file.WriteLine( settings[ i ] );
file.Close();
}
The problem is with you locking the file by initializing StreamWriter onto filePath and then trying to call File.WriteAllText which also internally attempts to lock the file and eventually end up with an exception being thrown.
Also from what it looks you are trying to clear the file's content and then write something in.
Consider the following:
private void writeTextFile(string filePath, string text) {
using (StreamWriter tw = new StreamWriter(filePath, false)) //second parameter is `Append` and false means override content
tw.WriteLine(text);
}
Why not use FileStream with FileMode.Create?
using (var fs = new FileStream(filePath, FileMode.Create, FileAccess.Write))
{
//Do something...
}
Look at the MSDN of FileMode Enum
Create
Specifies that the operating system should create a new file. If the file already exists, it will be overwritten. This requires Write permission. FileMode.Create is equivalent to requesting that if the file does not exist, use CreateNew; otherwise, use Truncate. If the file already exists but is a hidden file, an UnauthorizedAccessException exception is thrown.
Overwritten will cover/remove/clean/delete all existed file data.
if you would like to use StreamWriter, use new StreamWriter(fs).
I'm following Microsoft's tutorial on creating and writing to a simple file and I'm getting unexpected results.
http://msdn.microsoft.com/en-us/library/36b93480%28v=vs.110%29.aspx
Instead of writing a series of numbers to a file, I'm actually writing XML text to a file. But it's adding "Ł" to the very beginning and I don't know why.
Here's the code:
public static void CreateFile(string xml)
{
var dateStamp = DateTime.Now.ToString("yyyy-MM-dd");
var fileName = "file_" + dateStamp + ".xml";
if (File.Exists(fileName))
{
Console.WriteLine("File already exists.");
return;
}
using (FileStream fileStream = new FileStream(fileName, FileMode.CreateNew))
{
using (BinaryWriter writer = new BinaryWriter(fileStream))
{
writer.Write(xml);
}
}
}
When you read the manual for BinaryWriter.Write(string), it reads:
Writes a length-prefixed string to this stream…
So the “inappropriate” character is in fact the lenght of the string.
You should use a TextWriter-based writer instead (such as StreamWriter), or any other available method for outputting text files.
Also, you should pay attention to the encoding of the text. Specifically, when you are trying to output an XML, then if you had constructed it using .NET's XML manipulation means, and had it written into a string, then the <?xml?> directive will likely refer to utf-16 encoding. This is because .NET's strings use two-byte characters. Hence when dealing with XML, it is always better to use .NET's native means for serializing XML into text output (see e.g. XmlWriter). Only then the encoding will be correctly specified in the <?xml?> directive for sure.
That's because you are using a BinaryWriter to write the data to the file. It will write the string in a way that it can be read later, so it will write the string length first to the file, then the string data.
Just write the file as a text file instead. You can use a StreamWriter, or simply use one of the static helper methods in the File class that opens, writes and closes the file for you:
File.WriteAllText(fileName, xml);
This happens if you use a BinaryWriter. If you change it to a StreamWriter this problem goes away.
This is because the BinaryWriter adds the length (as int) of the writing string before.
public static void CreateFile(string xml)
{
var dateStamp = DateTime.Now.ToString("yyyy-MM-dd");
var fileName = "file_" + dateStamp + ".xml";
if (File.Exists(fileName))
{
Console.WriteLine("File already exists.");
return;
}
using (FileStream fileStream = new FileStream(fileName, FileMode.CreateNew))
{
using (StreamWriter writer = new StreamWriter(fileStream))
{
writer.Write(xml);
}
}
}
I want to append lines to my file. I am using a StreamWriter:
StreamWriter file2 = new StreamWriter(#"c:\file.txt");
file2.WriteLine(someString);
file2.Close();
The output of my file should be several strings below each other, but I have only one row, which is overwritten every time I run this code.
Is there some way to let the StreamWriter append to an existing file?
Use this instead:
new StreamWriter("c:\\file.txt", true);
With this overload of the StreamWriter constructor you choose if you append the file, or overwrite it.
C# 4 and above offers the following syntax, which some find more readable:
new StreamWriter("c:\\file.txt", append: true);
using (FileStream fs = new FileStream(fileName,FileMode.Append, FileAccess.Write))
using (StreamWriter sw = new StreamWriter(fs))
{
sw.WriteLine(something);
}
I assume you are executing all of the above code each time you write something to the file. Each time the stream for the file is opened, its seek pointer is positioned at the beginning so all writes end up overwriting what was there before.
You can solve the problem in two ways: either with the convenient
file2 = new StreamWriter("c:/file.txt", true);
or by explicitly repositioning the stream pointer yourself:
file2 = new StreamWriter("c:/file.txt");
file2.BaseStream.Seek(0, SeekOrigin.End);
Try this:
StreamWriter file2 = new StreamWriter(#"c:\file.txt", true);
file2.WriteLine(someString);
file2.Close();
Replace this:
StreamWriter file2 = new StreamWriter("c:/file.txt");
with this:
StreamWriter file2 = new StreamWriter("c:/file.txt", true);
true indicates that it appends text.
Actually only Jon's answer (Sep 5 '11 at 9:37) with BaseStream.Seek worked for my case. Thanks Jon! I needed to append lines to a zip archived txt file.
using (FileStream zipFS = new FileStream(#"c:\Temp\SFImport\test.zip",FileMode.OpenOrCreate))
{
using (ZipArchive arch = new ZipArchive(zipFS,ZipArchiveMode.Update))
{
ZipArchiveEntry entry = arch.GetEntry("testfile.txt");
if (entry == null)
{
entry = arch.CreateEntry("testfile.txt");
}
using (StreamWriter sw = new StreamWriter(entry.Open()))
{
sw.BaseStream.Seek(0,SeekOrigin.End);
sw.WriteLine("text content");
}
}
}
Use this StreamWriter constructor with 2nd parameter - true.
Another option is using System.IO.File.AppendText
This is equivalent to the StreamWriter overloads others have given.
Also File.AppendAllText may give a slightly easier interface without having to worry about opening and closing the stream. Though you may need to then worry about putting in your own linebreaks. :)
One more simple way is using the File.AppendText it appends UTF-8 encoded text to an existing file, or to a new file if the specified file does not exist and returns a System.IO.StreamWriter
using (System.IO.StreamWriter sw = System.IO.File.AppendText(logFilePath + "log.txt"))
{
sw.WriteLine("this is a log");
}
Replace this line:
StreamWriter sw = new StreamWriter("c:/file.txt");
with this code:
StreamWriter sw = File.AppendText("c:/file.txt");
and then write your line to the text file like this:
sw.WriteLine("text content");
You can use like this
using (System.IO.StreamWriter file =new System.IO.StreamWriter(FilePath,true))
{
`file.Write("SOme Text TO Write" + Environment.NewLine);
}
I want to take a file that stored already in the isolated storage, and copy it out, somewhere on the disk.
IsolatedStorageFile.CopyFile("storedFile.txt","c:\temp")
That doesn't work. Throws IsolatedStorageException and says "Operation not permitted"
I don't see anything in the docs, other than this, which just says that "Some operations aren't permitted", but doesn't say what, exactly. My guess is that it doesn't want you copying out of isolated storage to arbitrary locations on disk. The docs do state that the destination can't be a directory, but even if you fix that, you still get the same error.
As a workaround, you can open the file, read its contents, and write them to another file like so.
using (IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForAssembly())
{
//write sample file
using (Stream fs = new IsolatedStorageFileStream("test.txt", FileMode.Create, store))
{
StreamWriter w = new StreamWriter(fs);
w.WriteLine("test");
w.Flush();
}
//the following line will crash...
//store.CopyFile("test.txt", #"c:\test2.txt");
//open the file backup, read its contents, write them back out to
//your new file.
using (IsolatedStorageFileStream ifs = store.OpenFile("test.txt", FileMode.Open))
{
StreamReader reader = new StreamReader(ifs);
string contents = reader.ReadToEnd();
using (StreamWriter sw = new StreamWriter("nonisostorage.txt"))
{
sw.Write(contents);
}
}
}
I have a few multimillion lined text files located in a directory, I want to read line by line and replace “|” with “\” and then write out the line to a new file. This code might work just fine but I’m not seeing any resulting text file, or it might be I’m just be impatient.
{
string startingdir = #"K:\qload";
string dest = #"K:\D\ho\jlg\load\dest";
string[] files = Directory.GetFiles(startingdir, "*.txt");
foreach (string file in files)
{
StringBuilder sb = new StringBuilder();
using (FileStream fs = new FileStream(file, FileMode.Open))
using (StreamReader rdr = new StreamReader(fs))
{
while (!rdr.EndOfStream)
{
string begdocfile = rdr.ReadLine();
string replacementwork = docfile.Replace("|", "\\");
sb.AppendLine(replacementwork);
FileInfo file_info = new FileInfo(file);
string outputfilename = file_info.Name;
using (FileStream fs2 = new FileStream(dest + outputfilename, FileMode.Append))
using (StreamWriter writer = new StreamWriter(fs2))
{
writer.WriteLine(replacementwork);
}
}
}
}
}
DUHHHHH Thanks to everyone.
Id10t error.
Get rid of the StringBuilder, and do not reopen the output file for each line:
string startingdir = #"K:\qload";
string dest = #"K:\D\ho\jlg\load\dest";
string[] files = Directory.GetFiles(startingdir, "*.txt");
foreach (string file in files)
{
var outfile = Path.Combine(dest, Path.GetFileName(file));
using (StreamReader reader = new StreamReader(file))
using (StreamWriter writer = new StreamWriter(outfile))
{
string line = reader.ReadLine();
while (line != null)
{
writer.WriteLine(line.Replace("|", "\\"));
line = reader.ReadLine();
}
}
}
Why are you using a StringBuilder - you are just filling up your memory without doing anything with it.
You should also move the FileStream and StreamWriter using statements to outside of your loop - you are re-creating your output streams for every line, causing unneeded IO in the form of opening and closing the file.
Use Path.Combine(dest, outputfilename), from your code it looks like you're writing to the file K:\D\ho\jlg\load\destouputfilename.txt
This code might work just fine but I’m not seeing any resulting text file, or it might be I’m just be impatient.
Have you considered having a Console.WriteLine in there to check the progress. Sure, it's going to slow down performance a tiny tiny bit - but you'll know what's going on.
It looks like you might want to do a Path.Combine, so that instead of new FileStream(dest + outputfilename), you have new FileStream(Path.Combine(dest + outputfilename)), which will create the files in the directory that you expect, rather than creating them in K:\D\ho\jlg\load.
However, I'm not sure why you're writing to a StringBuilder that you're not using, or why you're opening and closing the file stream and stream writer on each line that you're writing, is that to force the writer to flush it's output? If so, it might be easier to just flush the writer/stream on each write.
you're opening and closing the output strean for each line in the output, you'll have to be very patient!
open it once outside the loop.
I guess the problem is here:
string begdocfile = rdr.ReadLine();
string replacementwork = docfile.Replace("|", "\\");
you're reading into begdocfile variable but replacing chars in docfile which I guess is empty
string replacementwork = docfile.Replace("|", "\\");
I believe the above line in your code is incorrect : it should be "begdocfile.Replace ..." ?
I suggest you focus on getting as much of the declaration and "name manufacture" out of the inner loop as possible : right now you are creating new FileInfo objects, and path names for every single line you read in every file : that's got to be hugely expensive.
make a single pass over the list of target files first, and create, at one time, the destination files, perhaps store them in a List for easy access, later. Or a Dictionary where "string" will be the new file path associated with that FileInfo ? Another strategy : just copy the whole directory once, and then operate to directly change the copied files : then rename them, rename the directory, whatever.
move every variable declaration out of that inner loop, and within the using code blocks you can.
I suspect you are going to hear from someone here at more of a "guru level" shortly who might suggest a different strategy based on a more profound knowledge of streams than I have, but that's a guess.
Good luck !