I don't see what's the matter here:
Constructor:
IsolatedStorageFile isf;
public FileManagement()
{
isf = IsolatedStorageFile.GetUserStoreForApplication();
}
when I save files:
public bool saveCredentials(String username, String userpass)
{
bool res = false;
StreamWriter writeFile = new StreamWriter(new IsolatedStorageFileStream("usercred.custom",
FileMode.Create, FileAccess.Write, isf));
writeFile.WriteLine(username);
writeFile.WriteLine(userpass);
res = true;
return res;
}
and when I try to read them:
public String readUsername()
{
String username = "";
IsolatedStorageFileStream fileStream = isf.OpenFile("usercred.custom", FileMode.Open, FileAccess.Read);
StreamReader reader = new StreamReader(fileStream);
username = reader.ReadLine();
return username;
}
Reading returns null.
I try to save a file and write something into it, but it somehow doesn't work.
You have to close your streams. Please add reader.Close(), writefile.Close() and fileStream.Close() before return and try again.
Related
I get a "file in use by another process exception" when creating a email and wants to add this file as attachment.
When i try to copy the same file to an other directory there is no problem. (state of the file is still the same)
does anybody knows whats happening here? and how i can solve this?
here is the code:
public Boolean AddAttachment(string filePath, string newName = "")
{
try
{
MimeData mime = _message.AddAttachment(filePath);
if (!string.IsNullOrEmpty(newName))
{
mime.FileName = newName;
}
return true;
}
catch (Exception err)
{
if (! AddAttachmentIfInUse(filePath, newName))
{
AddErrorInfo(err.Message, "AddAttachment", err.Source);
return false;
}
else
{
return true;
}
}
}
private Boolean AddAttachmentIfInUse(string filePath, string newName = "")
{
byte[] data;
string contentType = "";
string fileName = Path.GetFileName(filePath);
try
{
using (FileStream stream = File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.Read))
{
data = new byte[stream.Length];
stream.Read(data, 0, (int)stream.Length);
}
// data = File.ReadAllBytes(filePath);
MimeData mime = new MimeFactory().CreateMimeData();
mime.Data = data;
mime.ContentType = ContentType.Parse(contentType);
if (!string.IsNullOrEmpty(newName))
{
mime.FileName = newName;
}
else{
mime.FileName = fileName;
}
return true;
}
catch (Exception err)
{
AddErrorInfo(err.Message, "AddAttachmentIfInUse", err.Source);
return false;
}
}
thanks
The 1st function gets the the error in _message.AddAttachment(..) ...
I had to change the 2nd function: do not use File.Open() but use FileStream() and now it's working well.
using (var fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)){
data = new byte[fs.Length];
fs.Read(data, 0, (int)fs.Length);
}
I am trying to write to a file, I believe i am closing the file that i had read in earlier in the code, but I am getting a "System.IO.IO.Exception" This is my code for reading and writing to the file.
public class InOutTxt
{
public List<Employee> ReadFile(string fileName) {
FileStream fs = new FileStream(fileName,FileMode.Open ,FileAccess.ReadWrite);
StreamReader fileIn = new StreamReader(fileName);
fileIn = File.OpenText(fileName);
List<Employee> list = new List<Employee>();
string[] test;
string name;
string ID;
string dep;
string post;
while (!fileIn.EndOfStream || !File.Exists(fileName)) {
string inString = fileIn.ReadLine();
test = inString.Split('#');
name = test[0];
ID = test[1];
dep = test[2];
post = test[3];
Employee newEmp = new Employee(name, ID, dep, post);
list.Add(newEmp);
}
fileIn.Close();
fs.Close();
return list;
}
public void WriteFile(List<Employee> outList, string file) {
FileStream fs = new FileStream(file, FileMode.Open, FileAccess.ReadWrite);
StreamWriter writeOut = new StreamWriter(file);
for (int i = 0; i < outList.Count; i++) {
writeOut.WriteLine(outList[i].name + '#' + outList[i].IDnum + '#' + outList[i].department + '#' + outList[i].position);
}
writeOut.Close();
fs.Close();
}
}
The Error is occuring at this part of the code
StreamReader fileIn = new StreamReader(fileName);
If it helps any it was running well earlier today, the only major change I have made was the addition of the FileStream attribute above.
System.IO.IOException being used by another process
You have opened file using the FileStream constructor and the StreamReader gives error when it tries to open the file again using the fileName constructor. Pass the FileStream object instead of fileName.
FileStream Constructor (String, FileMode)
The constructor is given read/write access to the file, and it is
opened sharing Read access (that is, requests to open the file for
writing by this or another process will fail until the FileStream
object has been closed, but read attempts will succeed), MSDN.
//File is opened by FileStream and not available for opening before it is closed.
FileStream fs = new FileStream(fileName,FileMode.Open ,FileAccess.ReadWrite);
StreamReader fileIn = new StreamReader(fs); //Here pass fs instead of fileName
I have created one WCF service that will upload the file. and after using that service I am trying to upload the file I am able to successfully upload the file but there is some issue with the FILESTREAM class.
The moment i clicked the button to upload the file when i checked by debugging the application i get to know that stream object is null.
I am passing the object of stream class to the WCF method.
But due to some issue that stream object is getting null.
due to that null object of stream class, image which is uploded getting empty in my folder
This is my code that I am using to upload the file
if (FileUpload1.HasFile)
{
System.IO.FileInfo fileInfo = new System.IO.FileInfo(FileUpload1.PostedFile.FileName);
FileTransferServiceReference.ITransferService clientUpload = new FileTransferServiceReference.TransferServiceClient("BasicHttpBinding_ITransferService");
FileTransferServiceReference.RemoteFileInfo uploadRequestInfo = new RemoteFileInfo();
string Path = System.IO.Path.GetDirectoryName(FileUpload1.FileName);
using (System.IO.FileStream stream = new System.IO.FileStream(FileUpload1.FileName, System.IO.FileMode.Open, System.IO.FileAccess.Read))
{
uploadRequestInfo.FileName = FileUpload1.FileName;
uploadRequestInfo.Length = fileInfo.Length;
uploadRequestInfo.FileByteStream = stream;
clientUpload.UploadFile(uploadRequestInfo);
}
}
Code for WCF Service
public RemoteFileInfo DownloadFile(DownloadRequest request)
{
RemoteFileInfo result = new RemoteFileInfo();
try
{
// get some info about the input file
string filePath = System.IO.Path.Combine(#"c:\Uploadfiles", request.FileName);
System.IO.FileInfo fileInfo = new System.IO.FileInfo(filePath);
// check if exists
if (!fileInfo.Exists) throw new System.IO.FileNotFoundException("File not found", request.FileName);
// open stream
System.IO.FileStream stream = new System.IO.FileStream(filePath, System.IO.FileMode.Open, System.IO.FileAccess.Read);
// return result
result.FileName = request.FileName;
result.Length = fileInfo.Length;
result.FileByteStream = stream;
}
catch (Exception ex)
{
}
return result;
}
public void UploadFile(RemoteFileInfo request)
{
FileStream targetStream = null;
Stream sourceStream = request.FileByteStream;
string uploadFolder = #"C:\upload\";
if (!Directory.Exists(uploadFolder))
{
Directory.CreateDirectory(uploadFolder);
}
string filePath = Path.Combine(uploadFolder, request.FileName);
using (targetStream = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.None))
{
const int bufferLen = 65000;
byte[] buffer = new byte[bufferLen];
int count = 0;
while ((count = sourceStream.Read(buffer, 0, bufferLen)) > 0)
{
targetStream.Write(buffer, 0, count);
}
targetStream.Close();
sourceStream.Close();
}
}
}
Spot the difference:
string uploadFolder = #"C:\upload\";
...
string filePath = System.IO.Path.Combine(#"c:\Uploadfiles", request.FileName);
As a general tip you might put your upload file path into an external configuration file, so that you can change it when you move your application onto a server where you need to store the data on a different drive or in a specific location.
Also that way you are always calling the same configuration entry so your upload path name is definitely going to be the same everywhere.
I'm working now on a class that will allow editing very big text files (4Gb+). Well it may sound a little stupid but I do not understand how I can modify text in a stream.
Here is my code:
public long Replace(String text1, String text2)
{
long replaceCount = 0;
currentFileStream = File.Open(CurrentFileName, FileMode.Open, FileAccess.ReadWrite, FileShare.None);
using (BufferedStream bs = new BufferedStream(currentFileStream))
using (StreamReader sr = new StreamReader(bs))
{
string line;
while ((line = sr.ReadLine()) != null)
{
if (line.Contains(text1))
{
line.Replace(text1, text2);
// Here I should save changed line
replaceCount++;
}
}
}
return replaceCount;
}
You are not replacing it anywhere in your code. You should save all the text and then write it again to the file. Like,
public long Replace(String text1, String text2)
{
long replaceCount = 0;
currentFileStream = File.Open(CurrentFileName, FileMode.Open, FileAccess.ReadWrite, FileShare.None);
StringBuilder sb = new StringBuilder();
using (BufferedStream bs = new BufferedStream(currentFileStream))
using (StreamReader sr = new StreamReader(bs))
{
string line;
while ((line = sr.ReadLine()) != null)
{
string textToAdd = line;
if (line.Contains(text1))
{
textToAdd = line.Replace(text1, text2);
// Here I should save changed line
replaceCount++;
}
sb.Append(textToAdd);
}
}
using (FileStream fileStream = new FileStream(filename , fileMode, fileAccess))
{
StreamWriter streamWriter = new StreamWriter(fileStream);
streamWriter.Write(sb.ToString());
streamWriter.Close();
fileStream.Close();
}
return replaceCount;
}
I have a windows service writes its log in a text file in a simple format.
Now, I'm going to create a small application to read the service's log and shows both the existing log and the added one as live view.
The problem is that the service locks the text file for adding the new lines and at the same time the viewer application locks the file for reading.
The Service Code:
void WriteInLog(string logFilePath, data)
{
File.AppendAllText(logFilePath,
string.Format("{0} : {1}\r\n", DateTime.Now, data));
}
The viewer Code:
int index = 0;
private void Form1_Load(object sender, EventArgs e)
{
try
{
using (StreamReader sr = new StreamReader(logFilePath))
{
while (sr.Peek() >= 0) // reading the old data
{
AddLineToGrid(sr.ReadLine());
index++;
}
sr.Close();
}
timer1.Start();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void timer1_Tick(object sender, EventArgs e)
{
using (StreamReader sr = new StreamReader(logFilePath))
{
// skipping the old data, it has read in the Form1_Load event handler
for (int i = 0; i < index ; i++)
sr.ReadLine();
while (sr.Peek() >= 0) // reading the live data if exists
{
string str = sr.ReadLine();
if (str != null)
{
AddLineToGrid(str);
index++;
}
}
sr.Close();
}
}
Is there any problem in my code in reading and writing way?
How to solve the problem?
You need to make sure that both the service and the reader open the log file non-exclusively. Try this:
For the service - the writer in your example - use a FileStream instance created as follows:
var outStream = new FileStream(logfileName, FileMode.Open,
FileAccess.Write, FileShare.ReadWrite);
For the reader use the same but change the file access:
var inStream = new FileStream(logfileName, FileMode.Open,
FileAccess.Read, FileShare.ReadWrite);
Also, since FileStream implements IDisposable make sure that in both cases you consider using a using statement, for example for the writer:
using(var outStream = ...)
{
// using outStream here
...
}
Good luck!
Explicit set up the sharing mode while reading the text file.
using (FileStream fs = new FileStream(logFilePath,
FileMode.Open,
FileAccess.Read,
FileShare.ReadWrite))
{
using (StreamReader sr = new StreamReader(fs))
{
while (sr.Peek() >= 0) // reading the old data
{
AddLineToGrid(sr.ReadLine());
index++;
}
}
}
new StreamReader(File.Open(logFilePath,
FileMode.Open,
FileAccess.Read,
FileShare.ReadWrite))
-> this doesn't lock the file.
The problem is when you are writing to the log you are exclusively locking the file down so your StreamReader won't be allowed to open it at all.
You need to try open the file in readonly mode.
using (FileStream fs = new FileStream("myLogFile.txt", FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
using (StreamReader sr = new StreamReader(fs))
{
while (!fs.EndOfStream)
{
string line = fs.ReadLine();
// Your code here
}
}
}
I remember doing the same thing a couple of years ago. After some google queries i found this:
FileStream fs = new FileStream(#”c:\test.txt”,
FileMode.Open,
FileAccess.Read,
FileShare.ReadWrite);
i.e. use the FileShare.ReadWrite attribute on FileStream().
(found on Balaji Ramesh's blog)
Have you tried copying the file, then reading it?
Just update the copy whenever big changes are made.
This method will help you to fastest read a text file and without locking it.
private string ReadFileAndFetchStringInSingleLine(string file)
{
StringBuilder sb;
try
{
sb = new StringBuilder();
using (FileStream fs = File.Open(file, FileMode.Open))
{
using (BufferedStream bs = new BufferedStream(fs))
{
using (StreamReader sr = new StreamReader(bs))
{
string str;
while ((str = sr.ReadLine()) != null)
{
sb.Append(str);
}
}
}
}
return sb.ToString();
}
catch (Exception ex)
{
return "";
}
}
Hope this method will help you.