NotSupportedException gets thrown - c#

I am using C# to create a function to write data to a file in File System, and reate it and repeat function if file doesn't exist.
The first method of just writing the data is working. But the second method, if the file is not present and the program has to first create it, isn't working. It creates the file but at the very same time throws an exception to me in Visual Studio saying
System.NotSupportedException is unhandled
I am using the exact copy of code that the MSDN is having.
http://msdn.microsoft.com/en-us/library/d62kzs03(v=vs.110).aspx
Here is what I am using in my second code block,
// Create file!
using (FileStream fs = File.Create(file))
{
Byte[] info = new UTF8Encoding(true).GetBytes("some text in the file.");
// Add some information to the file.
fs.Write(info, 0, info.Length);
}
// Continue again with the request.
createFile(file);
The method declaration (if required) is as
private static void createFile (string fileName) {
string file = "C:\\Users\\AfzaalAhmad\\Documents\\" + fileName + ".txt";
/* two methods here */
}
The Image is as: (Note that there is no error in the path of file) I have used
Console.Write(file); // to get the path, and its OK!
See it in the image below ↓
Please note, that it does create the file in the Documents folder. But throws this exception. What am I doing wrong here?

Note the detail in the exception report: "The given path's format is not supported."
Also look at the contents of your variable file - it appears to be #"C:\Users\AfzaalAhmad\Documents\C:\Users..." - i.e. it contains the path twice.
So even though the operating system might have managed somehow to create some sort of file, the filename does not contain a valid value.
[edit] createFile(file); and Console.Write(file); are both taking the value #"C:\Users\AfzaalAhmad\Documents\dsg b.txt" but your method createFile is then adding the path a second time. Change it to simply:
private static void createFile (string file) {
/* two methods here */
}

Please have a exact look at the Exception message and the value of your file variable! There is your error!

Related

Exception thrown when starting StreamWriter

Every 24 hours, my code auto-generates a .csv-file, writes it temporarily to an Azure directory, and finally deletes it after operating on it.
It succeeds, but from the logs I can see, that an exception is thrown.
Exception:
"The process cannot access the file 'D:\home\site\wwwroot\myFile.csv'
because it is being used by another process."
The log points to these two lines of code, where I simply specify the directory and file-name and then start a StreamWriter:
string filePath = Environment.CurrentDirectory + "\\myFile.csv"; //Specify where to create csv on hosted Azure server (not locally)
using (var w = new StreamWriter(filePath, false, new UTF8Encoding(false))) //Exception is thrown here
{
//more code
}
I am very confused, how the two above lines can result in that exception, especially since the file is always deleted after upload.
For my particular case, the problem was that the StreamWriter code was executed twice, instead of the intended once. Thanks to user TheGeneral for guiding me in the right direction in the comments.

File.AppendAllText causes access exception to be thrown when program run for the second time

I have a log file that I delete and create every time my application is launched like so:
if (File.Exists(LogPath))
{
File.Delete(LogPath);
File.Create(LogPath);
}
And I'm writing in it using File.AppendAllText like so:
File.AppendAllText(LogPath, logMessage);
My issue is that when I run the program for the second time, the above call causes an exception to be thrown saying file can't be accessed
"because it is being used by another process"
What is wrong with this approach?
It's caused by File.Create(). Remove it and File.AppendAllText creates a new file if it doesn't exist.
Note:
File.Create() returns a FileStream value, if you do not dispose it, then it will cause an error when you want to access it.
This is not because of File.AppendAllText but instead this line of code:
File.Create(LogPath);
As per the documentation of File.Create(string):
Return Value
Type: System.IO.FileStream
A FileStream that provides read/write access to the file specified in path.
It returns an open FileStream object. You need to dispose of this object in order to close the stream and release the file. If you don't then this object will keep the file open until GC finalizes the object at some later indeterminate point in time.
Here's how to write this line of code, either one of the following two alternatives will work:
File.Create(LogPath).Dispose();
using (File.Create(LogPath)) { }
What happened is that the second time your program ran the file exists, so you deleted it and then recreated it, but the "recreated it" part kept the file open, so when it a short time later reached the File.AppendAllText method, the file was still open.
Note: If you always call File.AppendAllText you can simply just delete it, as AppendAllText will create the file if it doesn't already exist, as per the documentation of File.AppendAllText:
Opens a file, appends the specified string to the file, and then closes the file. If the file does not exist, this method creates a file, writes the specified string to the file, then closes the file.
(my emphasis)
You would need to close the file after you create for further processing.
if (File.Exists(LogPath))
{
File.Delete(LogPath);
using(var handler = File.Create(LogPath))
{
}
}
Other way could be to use WriteAllText and you won't need to delete it everytime.
File.WriteAllText(LogPath, "contents");
You, probably, mean
// clear the file (write an empty text to it) if it exists
if (File.Exists(LogPath))
{
File.WriteAllText(LogPath, "");
}
...
File.AppendAllText(LogPath, logMessage);
you can try combining clearing and writing in one call:
File.WriteAllText(LogPath, logMessage);
If the file exists, WriteAllText will clear it and write logMessage; if file doesn't exist, WriteAllText will create it and write logMessage.

Open jpeg from byte array

I have a program where the users can save an attachment for a contract. The attachment is saved in the database a a varbinary. The users can then view the attachment.
I am saving the file to a temp location while they view it and then deleting the file after the process is closed. This is working fine for word and excel documents but not for jpeg files.
File.WriteAllBytes(#"C:\Temp\" + SelectedAttachment.FileName + SelectedAttachment.FileType, SelectedAttachment.FileBlob);
//open the file for viewing
var attachmentProcess = System.Diagnostics.Process.Start(#"C:\Temp\" + SelectedAttachment.FileName + SelectedAttachment.FileType);
attachmentProcess.WaitForExit();
//Delete temp file after user closes the file
File.Delete(#"C:\Temp\" + SelectedAttachment.FileName + SelectedAttachment.FileType);
The attachmentProcess.WaitForExit(); throws an 'System.NullReferenceException' but was not handled in user code error when the .jpeg opens. The file will open regardless of the error but does not delete upon closing the file.
I have tried using
using (Image image = Image.FromStream(new MemoryStream(SelectedAttachment.FileBlob)))
{
image.Save("output.jpg", ImageFormat.Jpeg);
}
but i get an error stating that " 'Image': type used in a using statement must be implicitly convertible to 'System.IDisposable'
Is there a way to get the .jpeg file process to behave like the word or excel files or should I use the MemoryStream route and if so what am i doing wrong there?
You are using a static version of the Process.Start method and passing in a file name (which since it is an image, I'm guessing it is being treated like a url and opening in the web browser via file:///your-file-path/file-name). This actually returns null rather than a process, hence your error. You should instead pass in the name of a program (e.g. your web browser) and the filename as a parameter (using this version of the method).
Otherwise, consider creating a process object (via the new keyword, likely wrapped in a using statement) and calling the start method on that instance with your given StartInfo properties. This will ensure you have an actual process object in which to wait for exit.

Proper way of waiting until a file is created

I have the following code:
// get location where application data director is located
var appData = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
// create dir if it doesnt exist
var folder = System.IO.Path.Combine(appData, "SomeDir");
if (System.IO.Directory.Exists(folder) == false)
System.IO.Directory.CreateDirectory(folder);
// create file if it doesnt exist
var file = System.IO.Path.Combine(folder, "test.txt");
if(System.IO.File.Exists(file)== false)
System.IO.File.Create(file);
// write something to the file
System.IO.File.AppendAllText(file,"Foo");
This code crashes on the last line (An unhandled exception of type 'System.IO.IOException' occurred in mscorlib.dll). If I put a Thread.Sleep(400) after creating the file the code works great. What is the proper way of waiting until the file is created?
P.S.
I am using .net framework 3.5
Even if I wait it crashes :/
The reason for that is because File.Create is declared as:
public static FileStream Create(
string path
)
It returns a FileStream. The method is supposed to be used to create and open a file for writing. Since you never dispose of the returned FileStream object you're basically placing your bets on the garbage collector to collect that object before you need to rewrite the file.
So, to fix the problem with the naive solution you should dispose of that object:
System.IO.File.Create(file).Dispose();
Now, the gotcha here is that File.AppendAllText will in fact create the file if it does not exist so you don't even need that code, here is your full code with the unnecessary code removed:
// get location where application data director is located
var appData = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
// create dir if it doesnt exist
var folder = System.IO.Path.Combine(appData, "SomeDir");
System.IO.Directory.CreateDirectory(folder);
// write something to the file
var file = System.IO.Path.Combine(folder, "test.txt");
System.IO.File.AppendAllText(file,"Foo");
Directory.CreateDirectory will likewise not crash if the folder already exists so you can safely just call it.
There is no need to create the file if you intend to use File.AppendAllText
About the root cause for the error, and a preferred way to write to files in general:
The file was created, and returned a stream that you didn't use/close. best method should be to use this stream to write to the file.
using (FileStream fs = File.Create(file))
{
fs.Write("What ever you need to write..");
}

IsolatedStorageFile's MoveFile() method throws IsolatedStorageException

Description:
The code below is the simplest code I could write which causes the failure. I've also tried: putting the CreateFile and MoveFile in different using statements, putting them in different xaml pages, moving the file into a subdirectory with a new filename, moving it into a subdirectory with the same filename. They all throw the same exception. CopyFile throws the same exception in all circumstances.
Question is--what incredibly simple thing am I not accounting for?
Open a new Silverlight for Windows Phone 7 project targeting Windows Phone 7.1.
Open App.xaml.cs.
Paste the following lines of code into Application_Launching:
using (IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication())
{
isf.CreateFile("hello.txt");
isf.MoveFile("hello.txt", "hi.txt");
}
Click start debugging, targeting emulator or device.
Expected: creates a file named "hello.txt", then (effectively) renames "hello.txt" to "hi.txt".
Actual: throws exception below.
System.IO.IsolatedStorage.IsolatedStorageException was unhandled
Message=An error occurred while accessing IsolatedStorage.
StackTrace:
at System.IO.IsolatedStorage.IsolatedStorageFile.MoveFile(String sourceFileName, String destinationFileName)
at PhoneApp4.App.Application_Launching(Object sender, LaunchingEventArgs e)
at Microsoft.Phone.Shell.PhoneApplicationService.FireLaunching()
at Microsoft.Phone.Execution.NativeEmInterop.FireOnLaunching()
You should call Close after you create the file.
IsolatedStorageFileStream helloFile = store.CreateFile("hello.txt");
helloFile.Close();
isf.MoveFile("hello.txt", "hi.txt");
I was just having the same issue, but the solution is simple:
The target file must not exists, delete it before the moving. Make sure the target file is not open anywhere before deleting.
The source file must not be open anywhere.
if (_isolatedStorage.FileExists(targetPath))
{
_isolatedStorage.DeleteFile(targetPath);
}
_isolatedStorage.MoveFile(sourcePath, targetPath);
Perfectly execute this piece of code
var file = await ApplicationData.Current.LocalFolder.GetFileAsync(oldName);
await file.RenameAsync(newName);
MBen, your answer is not correct. Calling Close on the file does not fix this error. I am seeing the exact same error as well even though I call "Close" before MoveFile.
edit Ok just figured out the problem I was having - if you try to call MoveFile when the destinationFile already exists, it throws an Exception. You have to delete the destinationFile first before moving your sourceFile to it.

Categories