I'm writing a C# WinForms app using DirectX.AudioVideoPlayback (DirectX v9.0c). I open an audio file from a binary file, convert it to a Base64 string, string it into a byte array, then writie it to a temp file on the hard disk. I have a peculiar problem when opening a file from a temp file the second time around.
Here's the code:
private void OpenBinaryFile()
{
OpenFileDialog ofd = new OpenFileDialog();
ofd.Title = "Open Binary File...";
ofd.Multiselect = false;
ofd.Filter = "Binary File|*.bin";
if (DialogResult.OK == ofd.ShowDialog())
{
glbstrFilePath = ofd.FileName;
// Read Base64 string from binary file...
FileStream fs = new FileStream(ofd.FileName, FileMode.Open, FileAccess.Read);
BinaryReader br = new BinaryReader(fs);
strFileType = br.ReadString();
String strAudioString = br.ReadString();
fs.Close();
br.Close();
// Convert byte[] to audio...
byte[] AudioInBytes = Convert.FromBase64String(strAudioString);
File.WriteAllBytes(#"C:\MyTemp\thisaudio", AudioInBytes);
audio = Audio.FromFile(#"C:\MyTemp\thisaudio", false);
File.SetAttributes(#"C:\\MyTemp\\thisaudio", FileAttributes.Normal);
File.Delete(#"C:\MyTemp\thisaudio");
}
If I open a file once using the above code, the file opens, converts and loads without a problem. If I try to load a file again using the above code, I get this:
"System.UnauthorizedAccessException was unhandled HResult=
-2147024891 Message=Access to the path 'C:\MyTemp\thisaudio' is denied. Source=mscorlib"
So how can I prepare this app to open a file every time without crashing? I've tried setting the file's attributes to 'Normal' and running VS 2015 as Administrator, but neither works. I've googled "Access to path is denied C# WinForms DirectX.AudioVideoPlayback" and none of the search results, including many posted here on StackOverflow, have a solution that works for me. Also, I'll provide the full stack trace upon request.
According to https://msdn.microsoft.com/en-us/library/windows/desktop/bb324224(v=vs.85).aspx
the Audio class is disposable so you need to use using
using (var audio = Audio.FromFile(#"C:\MyTemp\thisaudio", false))
{
}
File.SetAttributes(#"C:\MyTemp\thisaudio", FileAttributes.Normal);
File.Delete(#"C:\MyTemp\thisaudio"); //edit: code correction
Related
So, I created a file and a txt file into the AppData, and I want to overwrite the txt. But when I try to do it, it keeps giving me that error. Any ideas?
string path = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
string setuppath = (path + "\\");
string nsetuppath = (setuppath + "newx" + "\\");
Directory.CreateDirectory(nsetuppath);
string hedef2 = (nsetuppath + "commands.txt");
File.Create(hedef2);
StreamWriter sw = new StreamWriter(hedef2); ----> This is where the error appears.
sw.WriteLine("Testtest");
Just use the using statement when using streams. The using statement automatically calls Dispose on the object when the code that is using it has completed.
//path to the file you want to create
string path = #"C:\code\Test.txt";
// Create the file, or overwrite if the file exists.
using (FileStream fs = File.Create(path))
{
byte[] info = new UTF8Encoding(true).GetBytes("This is some text in the file.");
// Add some information to the file.
fs.Write(info, 0, info.Length);
}
There are many ways of manipulate streams, keep it simple depending on your needs
I would like to create a bin file for example file.bin with the same content as a string variable contains. For example I have string str="10101" and I want to create conversion of str's content to bin file. After conversion, when I open file.bin I want to see the same content as str: 10101. I tried to do that by this way:
string path = "files/file.bin";
string str = "10101";
File.Create(path);
BinaryWriter bwStream = new BinaryWriter(new FileStream(path, FileMode.Create));
BinaryWriter binWriter = new BinaryWriter(File.Open(path, FileMode.Create));
for (int i = 0; i < str.Length; i++)
{
binWriter.Write(str[i]);
}
binWriter.Close();
but i get exception like
"System.IO.IOException: The process can not access the file
"C:\path.."
because it is being used by another process.. and few more exception.
The path/file you are trying to access is used by some other application. Close all the application which can/has opened the file,file.bin, which you are creating and then the code. It should work. You can remove bwStream variable line, if no other application is running.
You get the error because you are opening the file twice. The second time fails because the file is already open.
To write the string to the file you can just use the File.WriteAllText method:
string path = "files/file.bin";
string str = "10101";
File.WriteAllText(path, str);
Note: The string is encoded as utf-8 when it is written to the file.
File.Create() uses the file, try:
File.Create(path).Dispose();
BinaryWriter bwStream = new BinaryWriter(File.Open(path, FileMode.Append, FileAccess.Write, FileShare.ReadWrite));
I am trying to read all lines of log file that being used by some program.
When I tried to do it I am receiving exception:
System.IO.IOException was unhandled : file used by another process
So I searched on the web and found number of solutions:
C# exception. File is being used by another process
Read log file being used by another process
What's the least invasive way to read a locked file in C# (perhaps in unsafe mode)?
C# The process cannot access the file ''' because it is being used by another process
File is being used by another process
http://coding.infoconex.com/post/2009/04/21/How-do-I-open-a-file-that-is-in-use-in-C
The common solutions are to use using to wrap the FileStream and add the FileShare.ReadWrite.
I tried those solutions but I am still receiving the exception that the file is being used by another process.
In my below code I open the file D:\process.log to make the file used (for testing) and then trying to open the file.
The exception is on row:
using (FileStream fileStream = File.Open(i_FileNameAndPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
CODE:
private void openToolStripMenuItem_Click(object sender, EventArgs e)
{
OpenFileDialog openFileDialog = new OpenFileDialog();
DialogResult dialogResult = openFileDialog.ShowDialog();
if (dialogResult == DialogResult.OK)
{
listView.Items.Clear();
File.Open(#"D:\process.log", FileMode.Open); //make the file being used
String fileNameAndPath = openFileDialog.FileName;
String[] fileContent = readAllLines(fileNameAndPath);
}
}
private String[] readAllLines(String i_FileNameAndPath)
{
String[] o_Lines = null;
int i = 0;
using (FileStream fileStream = File.Open(i_FileNameAndPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
using (StreamReader streamReader = new StreamReader(fileStream))
{
while (streamReader.Peek() > -1)
{
String line = streamReader.ReadLine();
//o_Lines[i] = line;
i++;
}
}
}
return o_Lines;
}
use an overload of File.Open in your menuclick event handler like this:
File.Open(#"C:\process.log", FileMode.Open,FileAccess.ReadWrite, FileShare.ReadWrite);
The last param is a value specifying the type of access other threads have to the file.
see this article from msdn
My code goes like this:
using (var openFileDialogForImgUser = new OpenFileDialog())
{
string location = null;
string fileName = null;
string sourceFile = null;
string destFile = null;
string targetPath = #"..\..\Images";
openFileDialogForImgUser.Filter = "Image Files (*.jpg, *.png, *.gif, *.bmp)|*.jpg; *.png; *.gif; *.bmp|All Files (*.*)|*.*"; // filtering only picture file types
openFileDialogForImgUser.InitialDirectory = #"D:\My Pictures";
var openFileResult = openFileDialogForImgUser.ShowDialog(); // show the file open dialog box
if (openFileResult == DialogResult.OK)
{
using (var formSaveImg = new FormSave())
{
var saveResult = formSaveImg.ShowDialog();
if (saveResult == DialogResult.Yes)
{
imgUser.Image = new Bitmap(openFileDialogForImgUser.FileName); //showing the image opened in the picturebox
fileName = openFileDialogForImgUser.FileName;
location = Path.GetDirectoryName(fileName);
sourceFile = System.IO.Path.Combine(location, fileName);
destFile = System.IO.Path.Combine(targetPath, fileName);
if (!System.IO.Directory.Exists(targetPath))
{
System.IO.Directory.CreateDirectory(targetPath);
}
System.IO.File.Copy(sourceFile, destFile, true); /* error occurs at this line */
}
else
openFileDialogForImgUser.Dispose();
}
}
}
What I'm trying to do is that I am prompting the user to select an image in an OpenFileDialog, and copy that picture to a different directory (targetPath, specifically). Everything seems to work fine except for that one line: System.IO.File.Copy(sourceFile, destFile, true);.
It says that the file is used exclusively used by another process. And that happens for any image I select.
I'm trying to look at others' solution(s) to this problem --- I have to terminate (or wait) for the process that's using my file. If so, how do I do that? Or, if that's not the answer to this, what should I do? Note that this is the only piece of code that deals with image files in my C# solution.
I think your problem involves not disposing of the Bitmap object properly. If you create a Bitmap such that it reads from a file and you don't dispose it the file remains open and locked.
Here are a couple of links:
The dispose of an OpenFileDialog in C#?
C#: Dispose() a Bitmap object after call Bitmap.save()?
As I indicate in this answer https://stackoverflow.com/a/18172367/253938 my experience with using Bitmap and on-disk files is that it's best to never let Bitmap open the file. Instead, read the file into a byte array and use ImageConverter to convert it into an Image.
You need to close the file after you're done with. Use the .Close() property to close the file.
Once you open a file to read it/use it, it opens a background process. In order for that process to end, you need to also programatically close it using the .Close()
So your code needs to have a yourFile.Close() at the bottom of your code.
I am using DotNetZip.
What I need to do is to open up a zip files with files from the server.
The user can then grab the files and store it locally on their machine.
What I did before was the following:
string path = "Q:\\ZipFiles\\zip" + npnum + ".zip";
zip.Save(path);
Process.Start(path);
Note that Q: is a drive on the server. With Process.Start, it simply open up the zip file so that the user can access all the files. I like to do the same but not store the file on disk but show it from memory.
Now, instead of storing the zip file on the server, I like to open it up with MemoryStream
I have the following but does not seem to work
var ms = new MemoryStream();
zip.Save(ms);
but not sure how to proceed further in terms of opening up the zip file from a memory stream so that the user can access all the files
Here is a live piece of code (copied verbatim) which I wrote to download a series of blog posts as a zipped csv file. It's live and it works.
public ActionResult L2CSV()
{
var posts = _dataItemService.SelectStuff();
string csv = CSV.IEnumerableToCSV(posts);
// These first two lines simply get our required data as a long csv string
var fileData = Zip.CreateZip("LogPosts.csv", System.Text.Encoding.UTF8.GetBytes(csv));
var cd = new System.Net.Mime.ContentDisposition
{
FileName = "LogPosts.zip",
// always prompt the user for downloading, set to true if you want
// the browser to try to show the file inline
Inline = false,
};
Response.AppendHeader("Content-Disposition", cd.ToString());
return File(fileData, "application/octet-stream");
}
You can use:
zip.Save(ms);
// Set read point to beginning of stream
ms.Position = 0;
ZipFile newZip = ZipFile.Read(ms);
See the documentation for Create a zip using content obtained from a stream.
using (ZipFile zip = new ZipFile())
{
ZipEntry e= zip.AddEntry("Content-From-Stream.bin", "basedirectory", StreamToRead);
e.Comment = "The content for entry in the zip file was obtained from a stream";
zip.AddFile("Readme.txt");
zip.Save(zipFileToCreate);
}
After saving it, you can then open it up as normal.