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.
Related
I'm trying to read the contents of a file in a Visual Studio extension. The following code works, but forces me to open the file, if it isn't (otherwise it crashes):
textDocument = (TextDocument)projectItem.Document.Object("TextDocument");
EditPoint editPoint = textDocument.StartPoint.CreateEditPoint();
string text = editPoint.GetText(textDocument.EndPoint);
I can get the path of the project, so I suppose I could make an educated guess as to the location of the project item. However, ideally I'd like to either get the file contents without opening it; or, alternatively, get the path to the project item (then I could just use System.IO to access the file contents).
I've looked, but don't seem to be able to find any mention of either of these. Can anyone point me in the right direction, please?
You can get the path from a ProjectItem by reading its properties.
var path = YourProjectItem.Properties.Item("FullPath").Value.ToString()
After you have the path you can read its content with System.IO.
string content = File.ReadAllText(path);
If the file is somewhat larger and you are getting troubles with the current code due to size, you should take a look at the StreamReader class.
I'm not sure if this is possible for extensions but you could probably use System.IO, like this:
using System.IO;
string filePath = #"C:\Whatever\YourFileName.txt";
string fileText = File.ReadAllText(filePath);
You could also use StreamReader like this:
using System.IO;
string filePath = #"C:\Whatever\YourFileName.txt";
using (StreamReader sr = new StreamReader(filePath))
fileText = sr.ReadToEnd();
EDIT:
I think I understand you better now.
The only way to "get the file contents without opening it" would be if the extension were to give you that data actively, but I can safely assume it doesn't.
When reading a file, you should already know where the file is (if you don't know then either you're not intended to access that file or you just haven't looked long enough).
I'd try searching the SDK files manually (Or with a file crawler).
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.
I'm working with print jobs using PrintSystemJobInfo and this class doesn't have the path of the file (print job). So, I was wondering if there is a class where I can use the filename that is open (in memory) and this class return the full path. This file opened could be .doc, .pdf, .xls, .txt, and so on.
Please, someone can point me to the right direction or have an idea... it would be very helpful...
The only way for you to find open file handles is to use the NtQuerySystemInformation call. Here is a project that has this done as an explorer context menu. In this guy's case, he looks for files open in a specific folder.
You would then have to match the file name to the file you have in your print job.
By the way, this is not C# but you can wrap and call the same calls he is using. The rest is really up to you to figure out. ;)
Assuming you have a Stream object that is a FileStream then just do a cast and interrogation:
Stream str = printJob.JobStream;
FileStream fileStream = str as FileStream
if( fileStream != null ) {
String fileName = fileStream.Name;
}
I want to create a file that is in specific directory.
For example: C:\x\y\z\aTextFile.txt
For this operation, I have to create the directory to create file.
Directory.CreateDirectory(#"C:\x\y\z\");
File.Create(#"C:\x\y\z\aTextFile.txt");
But I really wonder that I can do this operation in single line of code.
Any help and idea will be greately appreciated.
Simple: Add a function
void MySingleLineOfCodeFunction(string path, string filename)
{
Directory.Createdirectory(path);
File.Create(filename).Dispose();
}
and then use a single line of code:
MySingleLineOfCodeFunction(#"C:\x\y\z\", "a.txt");
What I am trying to say is that there is no difference between code.
Some of it is written by the Microsoft guys, while other by us, normal people. But the computers don't make a difference. :)
As far I know, there is no File creation method that create the directory at the same time in the .NET framework.
If the pattern "Directory check/creation, then file creation" is repeated a lot in your code, you have to implement it in a method.
Unfortunately no there is no single line of code to do what you want.
Why? Because even if we do so by some Microsoft inbuilt function, internally it will be calling two methods. One for Directory creation and other for file creation.
However you can reduce your lines of code by making them into a method and call it in a single line as Petar Ivanov said
OR
You can create a static extension method. This way you can use it at other places without creating instance. (Reduced your one line where instance is created).
I've modified the answer from #Petar_Ivanov, to work out the parent directory based on the file path, thought it may be useful to others who might want a similar function.
public void CreateFile(string filePath)
{
if (!File.Exists(filePath))
{
var parent = Directory.GetParent(filePath);
Directory.CreateDirectory(parent.FullName);
File.Create(filePath).Dispose();
}
}
For creating a file, no, the directory has to exist. Even with Visual Basic's file friendly classes, you still have to create the directories first. What is interesting is that moving will create the folder.
From CreateFile http://msdn.microsoft.com/en-us/library/windows/desktop/aa363858(v=vs.85).aspx
Directories
An application cannot create a directory by using
CreateFile, therefore only the OPEN_EXISTING value is valid for
dwCreationDisposition for this use case. To create a directory, the
application must call CreateDirectory or CreateDirectoryEx
Mostly in my code blocks;
I handle folder existence right before file create parts.
public void CheckCreatePath(fileName)
{
string filePath = Directory.GetParent(fileName).ToString();
if (!Directory.Exists(filePath))
Directory.CreateDirectory(filePath);
}
and just use
CheckCreatePath("C:\\TEMP\\TESTPath\\myFile.txt");
in your code block.
I am getting the "The process cannot the file X because it is being used by another process" when I execute the following piece of code in my console application:
List<string> lines1 = new List<string>();
List<string> lines2 = new List<string>();
string path1 = ConfigurationManager.AppSettings.Get("path1");
string path2 = ConfigurationManager.AppSettings.Get("path2");
File.Create(path1);
File.Create(path2);
foreach (object myObject in myObjects)
{
//do some fancy logic here!!!
}
File.WriteAllLines(path1, lines1.ToArray()); //exception is thrown here
File.WriteAllLines(path2, lines2.ToArray());
How can I resolve this issue?
The likely problem here is the File.Create method. It's creating and returning a handle to the file in question wrapped in a FileStream object. That object is holding the file open for write and is hence blocking your later File.WriteAllLines call.
The simplest solution is to remove the File.Create calls. Just let the WriteAllLines method create the file for you
You have two options: File.Create not only creates the file but OPENS it. so you need to keep a reference to the filestream and close it like this:
var file1 = File.Create(path1);
var file2 = File.Create(path2);
file1.Close();
file2.Close();
OR you can just skip that because File.WriteAllLines(...) will create a file if it doesn't already exist.
You probably want to leverage something like File.Exist to prevent other exceptions, but that is not part of the present question.
File.Create(path1) is opening and keeping the file open and hence locking it.
File.WriteAllLines will create the file , so there is no need to create it first.
If you need to create it first (eg to test the path) you can do
FileStream fs = File.Create(path1);
fs.Close();
As per my comment above, File.Create(..) returns a FileStream object, which won't be destroyed until the method is closed (which means the handle is still open, thus file is still locked). When you're trying to use WriteAllLines it's attempting to open a new handle, and failing because one's already open.
You can use code like the following, which works fine (just tested):
List<string> lines1 = new List<string>();
string path1 = #"C:\Development\test1.txt";
for (int i = 0; i < 20; i++)
lines1.Add("Test " + i);
TextWriter textWriter = new StreamWriter(File.Create(path1));
foreach(string line in lines1)
textWriter.WriteLine(line);
textWriter.Close();
The code above will utilise the same stream that was created when the file was created, so you have no chance of collision.
Alternatively as in other answers, the File.WriteAllLines method will create the file for you anyway!
If you delete the File.Create lines, you should be fine. Unless you're doing something with the files in your foreach loop, you don't need to call the File.Create methods at all. The File.WriteAllLines will create a file if it doesn't exist. Since the File.WriteAllLines method also closes the filestream, you don't have to worry about managing the filestream returned by a File.Create.