I'm getting the IOException Error when I try this, and I'm not sure what I'm doing wrong:
This is my code:
FileStream fStream = new FileStream(PDFFilePath(), FileMode.CreateNew, FileAccess.ReadWrite);
Where
private string PDFFilePath()
{
m_sFilePath = "C:/Pictures/";
return m_sFilePath;
}
What am I missing?
I'm using this FileStream to save PDF documents using the Pdf.Select NuGet. It uses a method:
PdfDocument.Save(Stream stream);
I think you should be specifying your path this way:
private string PDFFilePath(string filename)
{
m_sFilePath = #"C:\Pictures\" + filename;
return m_sFilePath;
}
Like #Reisclef said, you have to provide a file path, not a directory. Since you're using FileMode.CreateNew, it has to be a new file, so you might also want to use File.Exists(m_sFilePath) before returning.
You have several problems here.
First, if you use a path like C:\Pictures\, it'll complain about the trailing \.
Secondly, you need to specify an actual file here, not just a directory. It makes no sense to just specify a directory (rather than a file) in this case - that's why it's called a File Stream and not a Directory Stream. I suggest using Path.Combine for this. Also, if you're just trying to move an already-existing file to this directory, you should do File.Move rather than using a FileStream.
Third, you only want to use FileMode.CreateNew if there's no possibility that the file already exists in the destination folder; if it does exist, this will throw an exception.
Fourth, it's a bad practice to hardcode paths like this. You usually want to get the path from a configuration file and make sure that the Pictures directory does, in fact, exist before you try to do this operation; otherwise it may fail when you deploy it to another machine.
Fifth, the PDFFilePath method seems rather pointless in this case - you can do the same thing with a string constant or creating a readonly string in the constructor.
Related
I'm trying to create a directory/folder, and at the same time insert an uploaded document to it. My code works. However, when I upload the file it goes to the same level as the newly created folder but I need it inside of it. How can I achieve that? here's what I have tried:
protected void ASPxButtonUpload_Click(object sender, EventArgs e)
{
using (Stream Fstream = e.UploadedFile.FileContent)
{
string folder = NewFile.User;
string Uploads = Server.MapUploads("~/Uploads/" + e.UploadedFile.FileName);
bool same = Directory.Exists(Uploads);
Fstream fs = new Fstream(Uploads, FileMode.Create, FileAccess.ReadWrite);
if (!same)
{
Directory.CreateDirectory(Path.Combine(Path.GetDirectoryName(Uploads), folder));
Fstream.CopyTo(fs); //**File that I need to include in the new folder**
}
}
}
I appreciate the help, Thanks!
When you create the destination file stream:
new FileStream(Path, FileMode.Create, FileAccess.ReadWrite)
That Path variable is the name of the file to which you're going to write. But there are a few issues here:
You're definining it before you define the folder, so it doesn't include that folder name.
You seem to be confusing directories with files in some of your paths.
You seem to be defining another variable called Path a few lines later, which is probably confusing you. (And I'm surprised it compiles.)
All in all, variable names like Path and FileStream are a super bad idea. They're not only against C# conventions, but more importantly they're guaranteed to confuse you because those are also the names of classes that you're using. (Again, I'm surprised this even compiles.)
First and foremost, rename your variables to something more sensible. Good naming helps everything else in the code, because it helps you understand the code.
After that, don't define the target file stream until you need to use it, and define it with the full path you want to use. It looks like the whole process should simply be to check if the folder exists, create it if it doesn't, and then write the file. Nothing more complex than that.
Untested, but perhaps something like this:
// define your paths
string rootFolder = Server.MapPath("~/Path/");
string outputFolder = Path.Combine(rootFolder, NewFile.User);
string targetFile = Path.Combine(outputFolder, e.UploadedFile.FileName);
// create the directory if needed
if (!Directory.Exists(outputFolder))
{
Directory.CreateDirectory(outputFolder);
}
// write the file
using (Stream inputFS = e.UploadedFile.FileContent)
{
FileStream outputFS = new FileStream(targetFile, FileMode.Create, FileAccess.ReadWrite);
inputFS.CopyTo(outputFS);
}
Keep your names clear, keep your operations simple. There's no need to over-complicate any of it.
I am doing editor in c#, windows forms. I wish to save 'new content' of file in the same file (usual usage of 'save' option) but I receive IOException, [ the process cannot access the file ' filename' because it is being used by another process.
I have method that writes to a NEW file and it works. How to use it to overwrite current file.
Edit:
I am using binarywriter http://msdn.microsoft.com/en-us/library/atxb4f07.aspx
Chances are that when you loaded the file, you didn't close the FileStream or whatever you used to read it. Always use a using statement for your streams (and other types implementing IDisposable), and it shouldn't be a problem. (Of course if you actually have that file open in a separate application, that's a different problem entirely.)
So instead of:
// Bad code
StreamReader reader = File.OpenText("foo.txt");
string data = reader.ReadToEnd();
// Nothing is closing the reader here! It'll keep an open
// file handle until it happens to be finalized
You should use something more like:
string data;
using (TextReader reader = File.OpenText("foo.txt"))
{
data = reader.ReadToEnd();
}
// Use data here - the handle will have been closed for you
Or ideally, use the methods in File which do it all for you:
string text = File.ReadAllText("foo.txt");
Check if you're closing stream to the file. If not then you're blocking yourself.
Assuming that you have correctly closed the stream you used to open and read the file initially, to create, append or fail depending of file existence you should use the FileMode parameter in FileStream constructor.
Everything depends on the way you open the FileStream, see here: FileStream Constructor (String, FileMode)
if you specify FileMode Create:
Specifies that the operating system should create a new file. If the
file already exists, it will be overwritten. This requires
FileIOPermissionAccess.Write. System.IO.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 is thrown.
Can I use FileInfo as such:
FileInfo fileInfo = new FileInfo(#"\\mymachine\downloads\;\\yourmachine\Log\" + "11.txt");
StreamWriter sw = fileInfo.CreateText();
sw.WriteLine("write some data");
sw.Close();
My lead thinks it can be used as such but I get an exception when I run that code..
Exception:
System.IO.DirectoryNotFoundException Could not find a part of the path
He thinks he can do a fake load balance and/or depending on which share is available the code will place an order file to be processed. I do not agree with his thinking but he my boss and i gotta do his biding..
The FileInfo constructor takes the path to a single file; what you're passing it is not a valid file name, so I'd expect an ArgumentException. What are you actually trying to accomplish here?
FileInfo just doesn't work like that. You're going to have to use something like File.Exists to see which file is available and then write code to write to one share or the other.
I have a string with a C# program that I want to write to a file and always overwrite the existing content. If the file isn't there, the program should create a new file instead of throwing an exception.
System.IO.File.WriteAllText (#"D:\path.txt", contents);
If the file exists, this overwrites it.
If the file does not exist, this creates it.
Please make sure you have appropriate privileges to write at the location, otherwise you will get an exception.
Use the File.WriteAllText method. It creates the file if it doesn't exist and overwrites it if it exists.
Generally, FileMode.Create is what you're looking for.
Use the file mode enum to change the File.Open behavior. This works for binary content as well as text.
Since FileMode.Open and FileMode.OpenOrCreate load the existing content to the file stream, if you want to replace the file completely you need to first clear the existing content, if any, before writing to the stream. FileMode.Truncate performs this step automatically
// OriginalFile:
oooooooooooooooooooooooooooooo
// NewFile:
----------------
// Write to file stream with FileMode.Open:
----------------oooooooooooooo
var exists = File.Exists(path);
var fileMode = exists
? FileMode.Truncate // overwrites all of the content of an existing file
: FileMode.CreateNew // creates a new file
using (var destinationStream = File.Open(path, fileMode)
{
await newContentStream.CopyToAsync(destinationStream);
}
FileMode Enum
If your code doesn't require the file to be truncated first, you can use the FileMode.OpenOrCreate to open the filestream, which will create the file if it doesn't exist or open it if it does. You can use the stream to point at the front and start overwriting the existing file?
I'm assuming your using a streams here, there are other ways to write a file.
I have a little problem with the File.Copy method in WPF, my code is very simple and I get an exception when I run it,
Could not find a part of the path 'Images\37c31987-52ee-4804-8601-a7b9b4d439fd.png'.
where Images is a relative folder.
Here is my code, as I said simple and the same code works fine in a console application, no problem at all.
string filenamae = System.IO.Path.Combine(images, Guid.NewGuid().ToString() + System.IO.Path.GetExtension(imageFile)); ;
System.IO.File.Copy(imageFile, filenamae);
this.ImageLocation = string.Empty;
So if any can help, thanks.
Does the images folder exist? File.Copy doesn't create it automatically.
Do you know what your current directory is? File open/save boxes can change that. So it's always safer to work with absolute paths.
Do a
Path.GetFullPath(filename)
and see where that points to. Is it the right location?
If you use the absolute instead of the relative path, does it work then?
Before you access a file, you should call System.IO.File.Exists(). It's not clear from your error description if the origin file exists or not before the copy.
If you don't specify an absolute path, your relative path with often be resolved from unexpected places, usually the current working directory of the process. Calling this method may tell you were the process is currently running:
System.IO.Directory.GetCurrentDirectory()
You should never make assumptions about the current working directory of a running process as the user could start your program from anywhere. Even if you think you always control the current working directory, you will be surprised how often you will be wrong.
Do you have a debugger? Why not insert a breakpoint and check the values used at each step?
If the file system says "cannot find file", I wouldn't bother arguing with it...
use \\ for the file path directory if it in local.. if your file exists in network path use \\\\(atfirst).. So that it look for network drive..
Thanks
It is necessary to embed all external files into the executable and change your code to work with these embedded files rather than to expect files on the disk.
To use images or whatever you need files("xml/txt/doc"), you need to set the build action of your file to Embedded Resource, and call the method with the fully qualified name of the file, where the name is assembled like this:
[RootNameSpaceOfTheProject].[NameOfFolderInTheProject].[FileNameWithExtension]
Example:
Call the method:
var b = ResourceOperations.GetResourceAsByteArray("Store.Resources.EmbeddedIcons.toolbox.png");
Now you can write the byte array to a temporary file for example and use this as an image source, or you can build an image from the byte array directly. At least, you've got your data...
and to save this files to a disk we should write a code by #Jon Skeet :
public static void CopyStream(Stream input, Stream output)
{
// Insert null checking here for production
byte[] buffer = new byte[8192];
int bytesRead;
while ((bytesRead = input.Read(buffer, 0, buffer.Length)) > 0)
{
output.Write(buffer, 0, bytesRead);
}
}
then call it:
using (Stream input = assembly.GetManifestResourceStream(resourceName))
using (Stream output = File.Create(path))
{
CopyStream(input, output);
}