I am trying to write some string to a file, and here is the code:
private static void WriteSelfDefinedFile(string msg)
{
ArrayList logTypes = SelfDefinedLogRule(msg);
// New some StreamWriter here
StreamWriter[] sws = new StreamWriter[selfDefinedLogFileName.Length];
for(int i = 0;i<selfDefinedLogFileName.Length;i++)
{
sws[i] = new StreamWriter(selfDefinedLogDir + selfDefinedLogFileName[i], true);
Debug.Log("111");
}
// It is writting here, not important for this question,I think.
foreach(SelfDefinedLogType temp in logTypes)
{
int index = (int)temp;
foreach (SelfDefinedLogType n in Enum.GetValues(typeof(SelfDefinedLogType)))
{
if(temp == n && sws[index]!=null)
{
sws[index].WriteLine(System.DateTime.Now.ToString() + ":\t"+ msg);
break;
}
else if(sws[index] == null)
{
LogError("File " + selfDefinedLogFileName[index] + " open fail");
}
}
}
// Close the StreamWrite[] here
for(int i=0;i<selfDefinedLogFileName.Length;i++)
{
sws[i].Close();
Debug.Log("222");
}
}
When the client is sending msg to server or server replying some msg to client, this funtion will be called to write some message to some files.
And unity throws the IOException:Sharing violation on path D:\SelfDefinedLogs\SentAndReceiveMsg.txt, sometimes. I mean, it doesn't happened everytime I write.
I have closed all the opened streamWriter at the end of the funtion, but the problem still come up.I am really confused.I will be grateful if anybody gives some solutions to this problem.
So I got the IOException: Attempted to Seek before the beginning of the stream. But when I looked into it the seek statement was inside of a using statement. I might be missunderstanding the using() because as far as I knew this initializes the in this case filestream before running the encased code.
private string saveLocation = string.Empty;
// This gets called inside the UI to visualize the save location
public string SaveLocation
{
get
{
if (string.IsNullOrEmpty(saveLocation))
{
saveLocation = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory) + #"\Pastes";
Initializer();
}
return saveLocation;
}
set { saveLocation = value; }
}
And this is the function it calls
private void Initializer()
{
// Check if the set save location exists
if (!Directory.Exists(saveLocation))
{
Debug.Log("Save location did not exist");
try
{
Directory.CreateDirectory(saveLocation);
}
catch (Exception e)
{
Debug.Log("Failed to create Directory: " + e);
return;
}
}
// Get executing assembly
if (string.IsNullOrEmpty(executingAssembly))
{
string codeBase = Assembly.GetExecutingAssembly().CodeBase;
UriBuilder uri = new UriBuilder(codeBase);
executingAssembly = Uri.UnescapeDataString(uri.Path);
}
// Get the last received list
if (!string.IsNullOrEmpty(executingAssembly))
{
var parent = Directory.GetParent(executingAssembly);
if (!File.Exists(parent + #"\ReceivedPastes.txt"))
{
// empty using to create file, so we don't have to clean up behind ourselfs.
using (FileStream fs = new FileStream(parent + #"\ReceivedPastes.txt", FileMode.CreateNew)) { }
}
else
{
using (FileStream fs = new FileStream(parent + #"\ReceivedPastes.txt", FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
if (fs.Seek(-20000, SeekOrigin.End) >= 0)
{
fs.Position = fs.Seek(-20000, SeekOrigin.End);
}
using (StreamReader sr = new StreamReader(fs))
{
while (sr.ReadLine() != null)
{
storedPastes.Add(sr.ReadLine());
}
}
}
}
}
isInitialized = true;
}
Are the commentors have posted: the file is less than 20000 bytes. It seems like you assume that Seek will stay at position 0 if the file is not large enough. It doesn't. It throws ArgumentException in that case.
Another thing. Seek will move the position for you. No need to do both. Either use:
fs.Seek(-20000, SeekOrigin.End);
or set the position:
fs.Position = fs.Length - 20000;
So what you really wanted to write is:
if (fs.Length > 20000)
fs.Seek(-20000, SeekOrigin.End);
After importing plenty of XML files into application i tried to do modifications on it by using XML document class, for this i created few methods to do modifications.
The thing is the starting method it's working fine and when comes to the second one it's displaying System.IO exception like "File is already using another process".
So any one help me out how can i solve this issue.
Sample code what i'm doing:
Method1(fileList);
Method2(fileList);
Method3(fileList);
private void Method1(IList<RenamedImportedFileInfo> fileList)
{
try
{
string isDefaultAttribute = Resource.Resources.ImportIsDefaultAttribute;
string editorsPath = editorsFolderName + Path.DirectorySeparatorChar + meterType;
string profilesPath = profileFolderName + Path.DirectorySeparatorChar + meterType;
string strUriAttribute = Resource.Resources.ImportUriAttribute;
foreach (RenamedImportedFileInfo renameInfo in fileList)
{
if (renameInfo.NewFilePath.ToString().Contains(editorsPath) && (renameInfo.IsProfileRenamed != true))
{
var xmldoc = new XmlDocument();
xmldoc.Load(renameInfo.NewFilePath);
if (xmldoc.DocumentElement.HasAttribute(isDefaultAttribute))
{
xmldoc.DocumentElement.Attributes[isDefaultAttribute].Value = Resource.Resources.ImportFalse;
}
XmlNodeList profileNodes = xmldoc.DocumentElement.GetElementsByTagName(Resource.Resources.ImportMeasurementProfileElement);
if (profileNodes.Count == 0)
{
profileNodes = xmldoc.DocumentElement.GetElementsByTagName(Resource.Resources.ImportBsMeasurementProfileElement);
}
if (profileNodes.Count > 0)
{
foreach (RenamedImportedFileInfo profileName in oRenamedImportedFileList)
{
if (profileName.NewFilePath.ToString().Contains(profilesPath))
{
if (string.Compare(Path.GetFileName(profileName.OldFilePath), Convert.ToString(profileNodes[0].Attributes[strUriAttribute].Value, CultureInfo.InvariantCulture), StringComparison.OrdinalIgnoreCase) == 0)
{
profileNodes[0].Attributes[strUriAttribute].Value = Path.GetFileName(profileName.NewFilePath);
renameInfo.IsProfileRenamed = true;
break;
}
}
}
}
xmldoc.Save(renameInfo.NewFilePath);
xmldoc = null;
profileNodes = null;
}
}
oRenamedImportedFileList = null;
}
catch (NullReferenceException nullException) { LastErrorMessage = nullException.Message; }
}
Thanks,
Raj
You are probably opening the same file twice in your application. Before you can open it again, you have to close it (or leave it open and work on the same document without opening it again).
For help on how to implement this, please show us more code so we can give you advice.
I'm trying to extract an ISO to a folder with the same name without .iso on the end.
I'm having a problem with winrar as it will not start the extract when I start up with the seach starting in the folder with the ISO.
UPDATED with answer code
private void ExtractISO(string toExtract, string folderName)
{
// reads the ISO
CDReader Reader = new CDReader(File.Open(toExtract, FileMode.Open), true);
// passes the root directory the folder name and the folder to extract
ExtractDirectory(Reader.Root, folderName /*+ Path.GetFileNameWithoutExtension(toExtract)*/ + "\\", "");
// clears reader and frees memory
Reader.Dispose();
}
private void ExtractDirectory(DiscDirectoryInfo Dinfo, string RootPath, string PathinISO)
{
if (!string.IsNullOrWhiteSpace(PathinISO))
{
PathinISO += "\\" + Dinfo.Name;
}
RootPath += "\\" + Dinfo.Name;
AppendDirectory(RootPath);
foreach (DiscDirectoryInfo dinfo in Dinfo.GetDirectories())
{
ExtractDirectory(dinfo, RootPath, PathinISO);
}
foreach (DiscFileInfo finfo in Dinfo.GetFiles())
{
using (Stream FileStr = finfo.OpenRead())
{
using (FileStream Fs = File.Create(RootPath + "\\" + finfo.Name)) // Here you can Set the BufferSize Also e.g. File.Create(RootPath + "\\" + finfo.Name, 4 * 1024)
{
FileStr.CopyTo(Fs, 4 * 1024); // Buffer Size is 4 * 1024 but you can modify it in your code as per your need
}
}
}
}
static void AppendDirectory(string path)
{
try
{
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
}
}
catch (DirectoryNotFoundException Ex)
{
AppendDirectory(Path.GetDirectoryName(path));
}
catch (PathTooLongException Ex)
{
AppendDirectory(Path.GetDirectoryName(path));
}
}
The user selects the folder to extract (.ISO) toExtract. I then use it in the Process.Start() in the background worker. That just seems to open the mounting software and doesn't extract the ISO to the desired folder name.
Thanks in advance for your help.
Or if anyone could give me a batch to extract the ISO instead and to call it from c# passing toExtract and the folder name that would be helpful too.
Thanks
If external Class Libraries are OK!
Then use SevenZipSharp or .NET DiscUtils to extract ISO's...
These two ClassLibraries can manage ISO and Extract them!
For DiscUtils you can find some codes for ISO Management [CDReader Class] at the Link I provided.
But For SevenZipSharp, Please Explore the ClassLibrary source and find the Code to Extract or Google to find it!
To get the Name of the folder just use Path.GetFileNameWithoutExtension((string)ISOFileName) which will return "ISOFile" for an iso named "ISOFile.iso". And then you can use it with your desired path.
UPDATE
Code To Extract ISO Image with DiscUtils :
using DiscUtils;
using DiscUtils.Iso9660;
void ExtractISO(string ISOName, string ExtractionPath)
{
using (FileStream ISOStream = File.Open(ISOName, FileMode.Open))
{
CDReader Reader = new CDReader(ISOStream, true, true);
ExtractDirectory(Reader.Root, ExtractionPath + Path.GetFileNameWithoutExtension(ISOName) + "\\", "");
Reader.Dispose();
}
}
void ExtractDirectory(DiscDirectoryInfo Dinfo, string RootPath, string PathinISO)
{
if (!string.IsNullOrWhiteSpace(PathinISO))
{
PathinISO += "\\" + Dinfo.Name;
}
RootPath += "\\" + Dinfo.Name;
AppendDirectory(RootPath);
foreach (DiscDirectoryInfo dinfo in Dinfo.GetDirectories())
{
ExtractDirectory(dinfo, RootPath, PathinISO);
}
foreach (DiscFileInfo finfo in Dinfo.GetFiles())
{
using (Stream FileStr = finfo.OpenRead())
{
using (FileStream Fs = File.Create(RootPath + "\\" + finfo.Name)) // Here you can Set the BufferSize Also e.g. File.Create(RootPath + "\\" + finfo.Name, 4 * 1024)
{
FileStr.CopyTo(Fs, 4 * 1024); // Buffer Size is 4 * 1024 but you can modify it in your code as per your need
}
}
}
}
static void AppendDirectory(string path)
{
try
{
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
}
}
catch (DirectoryNotFoundException Ex)
{
AppendDirectory(Path.GetDirectoryName(path));
}
catch (PathTooLongException Exx)
{
AppendDirectory(Path.GetDirectoryName(path));
}
}
Use It with Like This :
ExtractISO(ISOFileName, Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory) + "\\");
Working! Tested By Me!
And Of Course You can always add more Optimization to the code...
This Code is Just a Basic One!
For UDF or for making Windows ISO Files after servicing(DISM) with out needs the above accepted answer is not working for me so i tried this working method with DiscUtils
using DiscUtils;
public static void ReadIsoFile(string sIsoFile, string sDestinationRootPath)
{
Stream streamIsoFile = null;
try
{
streamIsoFile = new FileStream(sIsoFile, FileMode.Open);
DiscUtils.FileSystemInfo[] fsia = FileSystemManager.DetectDefaultFileSystems(streamIsoFile);
if (fsia.Length < 1)
{
MessageBox.Show("No valid disc file system detected.");
}
else
{
DiscFileSystem dfs = fsia[0].Open(streamIsoFile);
ReadIsoFolder(dfs, #"", sDestinationRootPath);
return;
}
}
finally
{
if (streamIsoFile != null)
{
streamIsoFile.Close();
}
}
}
public static void ReadIsoFolder(DiscFileSystem cdReader, string sIsoPath, string sDestinationRootPath)
{
try
{
string[] saFiles = cdReader.GetFiles(sIsoPath);
foreach (string sFile in saFiles)
{
DiscFileInfo dfiIso = cdReader.GetFileInfo(sFile);
string sDestinationPath = Path.Combine(sDestinationRootPath, dfiIso.DirectoryName.Substring(0, dfiIso.DirectoryName.Length - 1));
if (!Directory.Exists(sDestinationPath))
{
Directory.CreateDirectory(sDestinationPath);
}
string sDestinationFile = Path.Combine(sDestinationPath, dfiIso.Name);
SparseStream streamIsoFile = cdReader.OpenFile(sFile, FileMode.Open);
FileStream fsDest = new FileStream(sDestinationFile, FileMode.Create);
byte[] baData = new byte[0x4000];
while (true)
{
int nReadCount = streamIsoFile.Read(baData, 0, baData.Length);
if (nReadCount < 1)
{
break;
}
else
{
fsDest.Write(baData, 0, nReadCount);
}
}
streamIsoFile.Close();
fsDest.Close();
}
string[] saDirectories = cdReader.GetDirectories(sIsoPath);
foreach (string sDirectory in saDirectories)
{
ReadIsoFolder(cdReader, sDirectory, sDestinationRootPath);
}
return;
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
it has extracted from a application source ISOReader but modified for my requirements
total source is available at http://www.java2s.com/Open-Source/CSharp_Free_CodeDownload/i/isoreader.zip
Try this:
string Desktop = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
Process.Start("Winrar.exe", string.Format("x {0} {1}",
Desktop + "\\test.rar",
Desktop + "\\SomeFolder"));
That would extract the file test.rar to the folder SomeFolder. You can change the .rar extention to .iso, it'll work the same.
As far as I can see in your current code, there is no command given to extract a file, and no path to the file that has to be extracted. Try this example and let me know if it works =]
P.S. If you'd like to hide the extracting screen, you can set the YourProcessInfo.WindowStyle to ProcessWindowStyle.Hidden.
I hace confrunted recently with this kind of .iso extraction issue. After trying several methods, 7zip did the job for me, you just have to make sure that the latest version of 7zip is installed on your system. Maybe it will help
try
{
Process cmd = new Process();
cmd.StartInfo.FileName = "cmd.exe";
cmd.StartInfo.RedirectStandardInput = true;
cmd.StartInfo.RedirectStandardOutput = true;
cmd.StartInfo.CreateNoWindow = false;
cmd.StartInfo.UseShellExecute = false;
cmd.StartInfo.WindowStyle = ProcessWindowStyle.Normal;
cmd.Start();
cmd.StandardInput.WriteLine("C:");
//Console.WriteLine(cmd.StandardOutput.Read());
cmd.StandardInput.Flush();
cmd.StandardInput.WriteLine("cd C:\\\"Program Files\"\\7-Zip\\");
//Console.WriteLine(cmd.StandardOutput.ReadToEnd());
cmd.StandardInput.Flush();
cmd.StandardInput.WriteLine(string.Format("7z x -y -o{0} {1}", source, copyISOLocation.TempIsoPath));
//Console.WriteLine(cmd.StandardOutput.ReadToEnd());
cmd.StandardInput.Flush();
cmd.StandardInput.Close();
cmd.WaitForExit();
Console.WriteLine(cmd.StandardOutput.ReadToEnd());
}
catch (Exception e)
{
Console.WriteLine(e.Message + "\n" + e.StackTrace);
if (e.InnerException != null)
{
Console.WriteLine(e.InnerException.Message + "\n" + e.InnerException.StackTrace);
}
}
I'm trying to read from a binary file with BinaryReader.
This is how I call my reading method :
foreach (Movie film in TreeBuilder.myMovies)
{
if (File.Exists(#"C:\Users\DaPhunk\Documents\Visual Studio 2010\Projects\YLK\Binary\" + film.MovieName + ".txt"))
{
string[] myArray = operationManager.BinaryReading(film.MovieName);
if (myArray != null)
{
this.textStarring.Text = myArray[1];
this.textProduced.Text = myArray[2];
this.textMusic.Text = myArray[3];
this.textYear.Text = myArray[4];
this.textTime.Text = myArray[5];
}
else
{
MessageBox.Show("An error occured");
}
}
This is my reading method :
public string[] BinaryReading(string name)
{
FileStream myStream = new FileStream(#"C:\Users\DaPhunk\Documents\Visual Studio 2010\Projects\YLK\Binary\" + name + ".txt", FileMode.Open);
BinaryReader reader = new BinaryReader(myStream);
string loadString = reader.ReadString();
string[] loadArray = loadString.Split(',');
reader.Close();
myStream.Close();
return loadArray;
}
Now something within these lines is not working. My file is not empty because since it's only a string I can read whats in the file.
My problem is I'm trying to find whats wrong with a break point but as soon as I get past this line :
string loadString = reader.ReadString();
My program starts to run again. How is that possible ? This prevents me from checking what's inside my String[] and what are my values after the method call.
Any idea why ? Thanks in advance.
Update :
I tried to move my breakpoint here
string[] loadArray = loadString.Split(',');
But my program never stops so it never gets past the previous line.
Also this is my Writting method :
foreach (Movie film in TreeBuilder.myMovies)
{
if (film.MovieName == name)
{
FileStream myStream = new FileStream(#"C:\Users\DaPhunk\Documents\Visual Studio 2010\Projects\YLK\Binary\" + film.MovieName + ".txt", FileMode.Create);
BinaryWriter writer = new BinaryWriter(myStream);
writer.Write(film.MovieName + "," + starring + "," + produced + "," + music + "," + year + "," + lenght);
writer.Close();
myStream.Close();
}
}
Your string will be prefixed with a length field. That makes the .txt extension misleading.
Since it 'suddenly started working again' : is it possible you opened (and saved) one of the files with a Text editor?
Also, your current Read and Write methods are not thread-safe, you should enclose the Stream and Reader/Writer objects in using() {} statements.