Does anyone know of a way to (reasonably simple) create a file without actually opening/locking it? In File class, the methods for file creation always return a FileStream. What I want to do is to create a file, rename it (with File.Move) and then use it.
Now I have to:
Create it
Close
Rename
Reopen for use
Maybe you can try using File.WriteAllText Method (String, String)
with the file name and an empty string.
Creates a new file, writes the
specified string to the file, and then
closes the file. If the target file
already exists, it is overwritten.
using (File.Create(...)) { }
While this will briefly open your file (but close it again right away), the code should look quite unobtrusive.
Even if you did some P/Invoke call to a Win32 API function, you would get a file handle. I don't think there's a way to silently create a file without having it open right afterwards.
I think the real issue here is why you go about creating your file in the way you've planned. Creating a file in one place simply to move it to another location doesn't seem very efficient. Is there a particular reason for it?
What about using File.WriteAllBytes method?
// Summary:
// Creates a new file, writes the specified byte array to the file, and then
// closes the file. If the target file already exists, it is overwritten.
Another way is to use FileStream and Close it after creating the file. It will not lock the file. The code will look like:
FileStream fs = new FileStream(filePath, FileMode.Create);
fs.Flush(true);
fs.Close();
You just after this you can rename it as well or move it some other location.
Below is the Test program to test functionality.
using System;
using System.Collections.Generic;
using System.IO; using
System.Linq;
using System.Text;
namespace FileLocking {
class Program
{
static void Main(string[] args)
{
string str = #"C:\Test\TestFileLocking.Processing";
FileIOTest obj = new FileIOTest();
obj.CreateFile(str);
}
}
class FileIOTest
{
internal void CreateFile(string filePath)
{
try
{
//File.Create(filePath);
FileStream fs = new FileStream(filePath, FileMode.Create);
fs.Flush(true);
fs.Close();
TryToAccessFile(filePath);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
void TryToAccessFile(string filePath)
{
try
{
string newFile = Path.ChangeExtension(filePath, ".locked");
File.Move(filePath, newFile);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
} }
If you use File.Create(commented in above code) then it will give error saying file is being used by another process.
Incredibly grotty hack, probably the most complicated way to achieve your goal:
use Process class
processInfo = new ProcessStartInfo("cmd.exe", "/C " + Command);
processInfo.CreateNoWindow = true;
processInfo.UseShellExecute = false;
process = process.Start(processInfo);
process.WaitForExit();
where Command would be echo 2>> yourfile.txt
Related
This question already has answers here:
Easiest way to read from and write to files
(14 answers)
Closed 2 years ago.
Below is the code I have. My issue is that the file.txt is not created at all!
I cannot find the reason. Program should create it. Could you please help me ?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace WriteToFile
{
class Program
{
static void Main(string[] args)
{
string line = "Please help me to write something!!";
System.IO.StreamWriter file = new System.IO.StreamWriter
(#"C:\Users\jgonc\source\repos\WriteToFile\WriteToFile\bin\Debug\file.txt");
file.Flush();
file.WriteLine(line);
file.Close();
Console.WriteLine("press a key");
Console.ReadKey();
}
}
}
//line you want to write to the document
string line = "Please help me to write something!!";
//path to my documents
string docPath =
Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
using (StreamWriter sw = new StreamWriter(Path.Combine(docPath, "test.txt")))
{
sw.WriteLine(line);
}
Console.WriteLine("press a key");
Console.ReadKey();
Here I make use of the using keyword. This is extremely useful as any object created in the parameters will automatically be destroyed when the using segment ends which is great because it means you don't need to clutter your code with unnecessary flushes and closes.
Its also important you understand the difference between a flush & a close. Here when the using segment ends dispose is called on streamwriter which in turn calls close, which closes the stream. A flush is simply clearing the buffer.
Check that you the application has permission to write to my documents directory - here
I have changed the path to my documents as the bin folder often changes or is deleted.
Thank you for your support and hints.
I've investigate the permissions topic and it seems it was related to it.
After uninstalling my antivirus it started to work.
below is the final code, to write a couple of strings using StreamWriter.
static void Main(string[] args)
{
string[] lines = {
"Please help me to write something!",
"It's working now, it was related with my antivirus, it was somehow blocking my permissions to the folder",
"Thanks for your support and your hints!!",
};
//string path = #"C:\Users\jgonc\source\repos\WriteToFile\WriteToFile\bin\Debug\file.txt";
string path = #"file.txt";
System.IO.FileStream fs = new System.IO.FileStream(path, System.IO.FileMode.OpenOrCreate, System.IO.FileAccess.ReadWrite);
System.IO.StreamWriter file = new System.IO.StreamWriter(fs, System.Text.Encoding.ASCII);
if (!File.Exists(path))
{
Console.WriteLine("file was not created");
}
else
{
using (file)
{
foreach (string line in lines) {
file.WriteLine(line);
}
}
}
fs.Close();
Console.WriteLine("Press a Key to End...");
Console.ReadKey();
}
Try :
System.IO.StreamWriter file = new System.IO.StreamWriter
(#"C:\Users\jgonc\source\repos\WriteToFile\WriteToFile\bin\Debug\file.txt", true);
true for append attribute set it false if you want to create file every time.
I am trying to delete a folder but am getting the following error message:
The process cannot access the file .it is being used by another process.
string target_dir="D:\\projectpath\\page";
if (Directory.Exists(target_dir))
Directory.Delete(target_dir, false);
How can I resolve this error?
It looks like the file is locked by some other process. This could happen if when reading/writing to it you forgot to dispose the stream reader/writer and you leaked the unmanaged handler to the file.
For example if you used the following code to read from the file:
StreamReader reader = new StreamReader(fileName);
string contents = reader.ReadToEnd();
and you never release the reader, the file will be locked. The proper way is to wrap IDisposable resources such as Streams and StreamReaders in using statements:
using (StreamReader reader = new StreamReader(fileName))
{
string contents = reader.ReadToEnd();
}
If on the other hand the file is locked by some other external process to your application then there's very little you could do about it, other than killing this process.
I think on the surface, your problem should be apparent: the file is in use by something else, so you can't delete the directory it resides in. If there was a way to "force delete" the file, it could cause other programs to crash. I'd recommend catching the error and either logging it or displaying it to the user, so they can decide if they really want to delete the in-use file.
If you MUST delete the file, you could take a look at:
Using C#, how does one figure out what process locked a file?
And once you know what the process is, you can then kill it, which should free up the file. Again, this isn't a good practice and should only be used in exceptional circumstances.
To delete the diectory you must have the correct Permissions.
var target_dir = "D:\\projectpath\page";
var isWriteAccess = false;
try
{
var collection = Directory.GetAccessControl(target_dir)
.GetAccessRules(true, true, typeof(System.Security.Principal.NTAccount));
if (collection.Cast<FileSystemAccessRule>().Any(rule => rule.AccessControlType == AccessControlType.Allow))
{
isWriteAccess = true;
}
}
catch (UnauthorizedAccessException ex)
{
isWriteAccess = false;
}
catch (Exception ex)
{
isWriteAccess = false;
}
if (!isWriteAccess)
{
MessageBox.Show("no access to directory.");
// Handle here close and kill the blocking process
}
else
{
Directory.Delete(target_dir, false);
}
}
So, I'm trying to create a login form, but I need to read and write to files etc, first of all; I'm creating a file then writing 'test' to the file, but if I then delete the file and try and issue my commands at the same time:
FileIO.FileCheck("Usernames.pheonix");
FileIO.WriteFile("Usernames.pheonix", "test");
It pulls me an error;
The process cannot access the file 'C:\Users\XXX\Desktop\Pheonix Launcher\Pheonix\bin\Debug\Usernames.pheonix' because it is being used by another process.
I can't seem to get me head around why it keeps on doing this, here are my Read/Write file:
public static void createFile(String FileName)
{
File.Create(FileName);
}
public static void WriteFile(String File ,String Message)
{
FileStream fs1 = new FileStream(File, FileMode.OpenOrCreate, FileAccess.Write);
StreamWriter writer = new StreamWriter(fs1);
writer.Write(Message);
writer.Close();
}
public static void FileCheck(String fileName)
{
if (File.Exists(fileName))
Console.WriteLine("File exists.");
else
createFile(fileName);
}
File.Create does create a file - and return an open stream to it. Put it in a using block. (Don't just call close on it - that would be a bug because it is not exception safe).
Actually, looking closer I see that you don't need this at all due to FileMode.OpenOrCreate. The file will be created anyway.
When I create my log.txt with File.Create(Path.Combine(PATH, NAME)); and then try to read from it I get an exception: {System.IO.IOException: The process cannot access the file 'c:\temp\log.txt' because it is being used by another process..
If the log.txt file exits and not created in the method I can read and write to the log wihtout any problems.
Is the log.txt created async and the problem is that the program is trying to read it before it's created?
public static void WriteToLog(string text)
{
try
{
if (!Directory.Exists(PATH))
{
Directory.CreateDirectory(PATH);
}
if( !File.Exists(Path.Combine(PATH, NAME)) )
{
File.Create(Path.Combine(PATH, NAME));
}
var logLines = File.ReadAllLines(Path.Combine(PATH, NAME)).ToList<string>();
logLines.Insert(0, "-------------------------------------------------End New Log");
logLines.Insert(0, text);
logLines.Insert(0, "-------------------------------------------------Start New Log");
File.WriteAllLines(Path.Combine(PATH, NAME), logLines);
}
catch (Exception ex)
{
}
}
File.Create creates a filestream, which is open after the creation. so the file is used by its own process.
just change it to
using(var f = File.Create(Path.Combine(PATH, NAME))) { } ;
File.Create has a return value of type FileStream. That FileStream should be Closed (or Disposed) if you do not intend to use it for anything.
For a log file, however, I'd usually create the FileStream directly by constructing a FileStream object, using one of the constructors that accepts a FileShare parameter. That way, you can keep the stream open, but indicate that other programs should be able to open it for reading:
var fs = new FileStream(Path.Combine(PATH, NAME),
FileMode.OpenOrCreate,
FileAccess.Write,
FileShare.Read); //Now other people can access the log file whilst I'm still writing to it
public void LoadRealmlist()
{
try
{
File.Delete(Properties.Settings.Default.WoWFolderLocation +
"Data/realmlist.wtf");
StreamWriter TheWriter =
new StreamWriter(Properties.Settings.Default.WoWFolderLocation +
"Data/realmlist.wtf");
TheWriter.WriteLine("this is my test string");
TheWriter.Close();
}
catch (Exception)
{
}
}
Will my method properly delete a file, then create one with "realmlist.wtf" as the name and then write a line to it?
I'm kind of confused because I can't see the line where it actually creates the file again. Or does the act of creating a StreamWriter automatically create a file?
The Stream Writer will create the file if it doesn't exist.
It will create it in the constructor, so when the StreamWriter is instantiated.
You know, if you pass a FileStream instance to the StreamWriter constructor, it can be set to simply overwrite the file. Just pass it along with the constructor.
http://msdn.microsoft.com/en-us/library/system.io.filestream.filestream.aspx
Example:
try
{
using (FileStream fs = new FileStream(filename, FileMode.Create))
{
//FileMode.Create will make sure that if the file allready exists,
//it is deleted and a new one create. If not, it is created normally.
using (StreamWriter sw = new StreamWriter(fs))
{
//whatever you wanna do.
}
}
}
catch (Exception e)
{
System.Diagnostics.Debug.WriteLine(e.Message);
}
Also, with this you won't need to use the .Close method. The using() function does that for you.
Try System.IO.File.CreateText.