Compare time between a log file and an image file - c#

I have 1000's of images and more than 100,000 lines of log files. I need to check if there exists an image that is associated with each unix time in log file. To do this, I first read thru all the images and stored time information in an array. Then I read thru all the lines of the log file, split each information (lat, long, time) and stored them in an array. Finally, I am taking one time element at a time and checking if it matches with image time array. If no match is found, I get the time from log, get lat and long from the same array and write it to a text file. But the overall process takes very long time. I am looking into efficiencies on how to make this process faster.
var fileList = Directory.GetFiles(imageLocation, "*.jpg");
//Array that will store all the time information obtained from image property
double[] imgTimeInfo = new double[fileList.Length];
int imgTimeCounter =0;
foreach (var fileName in fileList)
{
x++;
string fileNameShort = fileName.Substring(fileName.LastIndexOf('\\') + 1);
richTextBox1.AppendText("Getting time information from image " + x + " of " + fileList.Length + " : " + fileNameShort + Environment.NewLine);
richTextBox1.Refresh();
using (var fs = File.OpenRead(fileName))
{
//create an instance of a bitmap image
var image = new Bitmap(fs);
//get the date/time image property of the image
PropertyItem property = image.GetPropertyItem(36867);
System.Text.Encoding encoding = new System.Text.ASCIIEncoding();
string valueFrmProperty = encoding.GetString(property.Value);
//Format the value obtained to convert it into unix equivalent for comparison
string valueCorrected = valueFrmProperty.Split(' ')[0].Replace(":", "/") + " " + valueFrmProperty.Split(' ')[1];
var unixTime = ConvertToUnixTimeStamp(DateTime.Parse(valueCorrected));
imgTimeInfo[imgTimeCounter] = unixTime;
imgTimeCounter++;
//It is very important to dispose the image resource before trying to read the property of another image. image.dispose frees the resources or else we get
//outofmemoryexception.
image.Dispose();
}
}
MessageBox.Show("Images done.");
richTextBox1.AppendText("Fetching time information from log files..."+Environment.NewLine);
richTextBox1.Refresh();
int counter4Time = contentBathy.Length / 6;
//assign counter for lat,long and time
int timeCounter = 3;
for (int i = 0; i < counter4Time; i++)
{
richTextBox1.AppendText("Searching time match with image files..." + Environment.NewLine);
richTextBox1.Refresh();
double timeValue = Int32.Parse(contentBathy[timeCounter]);
//Looks for values that is +- 3 seconds different in the image file.
if (Array.Exists(imgTimeInfo, a => a == timeValue || a == timeValue + 1 || a == timeValue + 2|| a == timeValue+3
||a == timeValue-1|| a== timeValue-2||a == timeValue-3))
{
File.AppendAllText(#"c:\temp\matched.txt", "Lat : " + contentBathy[timeCounter - 3] + " Log : " + contentBathy[timeCounter - 2] + Environment.NewLine);
richTextBox1.AppendText("Image with same time information found. Looking for another match."+ Environment.NewLine);
}
else
{
//richTextBox1.AppendText("Time did not match...Writing GPX cordinates..." + Environment.NewLine);
//richTextBox1.Refresh();
File.AppendAllText(gpxLocation, "Lat : " + contentBathy[timeCounter - 3] + " Log : " + contentBathy[timeCounter - 2] + Environment.NewLine);
}
if(timeCounter < contentBathy.Length-3)
timeCounter += 6;
}
}

Related

System.IO.File.WriteAllText outputs gibberish C#

I have a simple program in C# that is supposed to output a text file containing a sequence of character separated by commas. I also output the resulting sequence on the console and it looks fine, however, the text file is full of weird character and no commas.
This is the output :
㔳㌬ⰵⰴⰴⰴⰴⰴⰴⰴⰴⰴⰴⰴⰴⰴⰴⰴⰴⰴⰴⰴⰴⰴⰴⰴⰴⰴⰴⰴⰴⰴⰴⰴⰴⰴⰴⰴⰴⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰴⰴⰴⰴⰴⰴⰴⰴⰴⰴⰴⰴⰴⰴⰴⰴⰴⰴⰴⰴⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰴⰴⰴⰴⰴⰴⰴⰴⰴⰴⰰⰰⰰⰰⰰⰰⰴⰴⰴⰴⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰴⰴⰴⰴⰴⰴⰴⰴⰴⰰⰰⰰⰰⰰⰰⰰⰴⰴⰴⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰴⰴⰴⰴⰴⰴⰰⰰⰰⰰⰳⰰⰰⰰⰴⰴⰴⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰴⰴⰴⰰⰰⰰⰰⰴⰰⰰⰰⰳⰰⰴⰴⰴⰰⰰⰰⰰⰰⰰⰰⰴⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰴⰴⰴⰰⰰⰰⰰⰴⰴⰴⰰⰰⰰⰰⰰⰰⰴⰴⰴⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰴⰴⰴⰴⰰⰰⰰⰰⰴⰴⰴⰰⰰⰰⰰⰰⰰⰴⰴⰴⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰴⰴⰴⰴⰰⰰⰰⰴⰴⰴⰴⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰴⰴⰴⰴⰴⰰⰰⰴⰴⰴⰴⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰲⰱⰱⰱⰰⰰⰰⰰⰰⰰⰰⰰⰰⰴⰴⰴⰴⰴⰰⰰⰴⰴⰴⰴⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰱⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰴⰴⰴⰴⰰⰰⰴⰴⰴⰴⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰲⰰⰳⰱⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰴⰴⰴⰴⰰⰰⰴⰴⰴⰴⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰱⰱⰱⰱⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰴⰴⰴⰴⰰⰰⰴⰴⰴⰴⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰴⰴⰴⰰⰰⰴⰴⰴⰴⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰴⰴⰰⰰⰰⰰⰴⰴⰴⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰴⰴⰰⰰⰳⰰⰴⰴⰴⰰⰰⰰⰴⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰴⰴⰰⰰⰰⰰⰴⰴⰴⰰⰰⰴⰴⰴⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰱⰱⰱⰱⰱⰱⰲⰰⰲⰱⰱⰴⰴⰰⰰⰴⰴⰴⰴⰰⰰⰴⰴⰴⰴⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰱⰰⰰⰰⰰⰰⰰⰰⰰⰰⰱⰴⰴⰰⰰⰴⰴⰴⰴⰰⰰⰰⰰⰴⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰱⰰⰰⰰⰰⰰⰵⰰⰵⰰⰱⰴⰴⰰⰰⰴⰴⰴⰴⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰲⰰⰰⰰⰰⰰⰰⰰⰰⰰⰱⰴⰴⰰⰰⰴⰴⰴⰴⰰⰰⰰⰰⰰⰰⰰⰰⰰⰴⰴⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰵⰰⰵⰰⰱⰴⰴⰰⰰⰴⰴⰴⰴⰰⰰⰰⰰⰰⰰⰰⰰⰴⰴⰴⰴⰰⰰⰰⰰⰲⰰⰰⰵⰰⰰⰰⰰⰰⰰⰱⰴⰴⰰⰰⰴⰴⰴⰴⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰴⰴⰴⰰⰰⰰⰱⰰⰰⰰⰰⰰⰰⰰⰰⰰⰱⰴⰴⰰⰰⰴⰴⰴⰴⰰⰰⰰⰰⰰⰰⰵⰰⰰⰰⰴⰴⰰⰰⰰⰰⰱⰱⰱⰱⰱⰱⰰⰰⰱⰱⰱⰴⰴⰰⰰⰴⰴⰴⰴⰰⰰⰰⰵⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰴⰴⰴⰰⰰⰴⰴⰴⰴⰴⰰⰰⰴⰴⰴⰴⰰⰰⰰⰰⰰⰰⰰⰵⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰴⰴⰴⰴⰰⰰⰰⰰⰰⰰⰰⰰⰰⰴⰴⰴⰴⰰⰰⰰⰰⰰⰵⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰴⰴⰴⰴⰴⰴⰴⰰⰰⰰⰰⰰⰴⰴⰴⰴⰴⰴⰴⰰⰰⰵⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰴⰴⰴⰴⰴⰴⰴⰴⰴⰰⰰⰳⰰⰴⰴⰴⰴⰴⰴⰴⰰⰰⰰⰰⰰⰵⰰⰰⰰⰴⰴⰴⰴⰰⰰⰴⰴⰴⰴⰴⰴⰴⰴⰰⰰⰰⰰⰰⰴⰴⰴⰴⰴⰴⰴⰰⰰⰰⰰⰰⰰⰰⰰⰴⰴⰴⰴⰴⰰⰰⰴⰴⰴⰴⰴⰴⰴⰴⰴⰰⰰⰰⰴⰴⰴⰴⰴⰴⰴⰴⰰⰰⰰⰰⰰⰰⰰⰰⰴⰴⰴⰴⰴⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰰⰴⰴⰴⰴⰴⰴⰴⰴⰴⰴⰰⰰⰰⰰⰰⰰⰴⰴⰴⰴⰴⰴⰴⰴⰴⰴⰴⰴⰴⰴⰴⰴⰴⰴⰴⰴⰴⰴⰴⰴⰴⰴⰴⰴⰴⰴⰴⰴⰴⰴⰴⰴⰴⰴⰴⰴⰴⰴⰴⰴⰴⰴⰴⰴⰴⰴⰴⰴⰴⰴⰴⰴⰴⰴⰴⰴⰴⰴⰴ
This is what is supposed to be outputted
35,35,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,4,4,0,0,0,0,0,0,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,4,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,4,4,4,4,4,4,0,0,0,0,3,0,0,0,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,
4,0,0,0,0,4,0,0,0,3,0,4,4,4,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,
4,4,0,0,0,0,4,4,4,0,0,0,0,0,0,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,4,4,0,0,0,
0,4,4,4,0,0,0,0,0,0,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,4,4,0,0,0,4,4,4,4,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,4,4,4,0,0,4,4,4,4,0,0,0,0,0,0,
0,0,0,0,0,2,1,1,1,0,0,0,0,0,0,0,0,0,4,4,4,4,4,0,0,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,1,0,0,0,0,0,0,0,0,0,0,4,4,4,4,0,0,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,2,0,3,1,0,
0,0,0,0,0,0,0,0,0,4,4,4,4,0,0,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,
0,0,0,0,4,4,4,4,0,0,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
4,4,4,0,0,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,0,0,0,
0,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,0,0,3,0,4,4,4,0,
0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,0,0,0,0,4,4,4,0,0,4,4,4,0,
0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,2,0,2,1,1,4,4,0,0,4,4,4,4,0,0,4,4,4,4,0,0,0,0,0,
0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,4,4,0,0,4,4,4,4,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,
1,0,0,0,0,0,5,0,5,0,1,4,4,0,0,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,
0,0,0,0,0,1,4,4,0,0,4,4,4,4,0,0,0,0,0,0,0,0,0,4,4,0,0,0,0,0,0,0,0,0,0,0,5,0,5,0,
1,4,4,0,0,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,0,0,0,0,2,0,0,5,0,0,0,0,0,0,1,4,4,0,0,
4,4,4,4,0,0,0,0,0,0,0,0,0,0,4,4,4,0,0,0,1,0,0,0,0,0,0,0,0,0,1,4,4,0,0,4,4,4,4,0,
0,0,0,0,0,5,0,0,0,4,4,0,0,0,0,1,1,1,1,1,1,0,0,1,1,1,4,4,0,0,4,4,4,4,0,0,0,5,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,4,0,0,4,4,4,4,4,0,0,4,4,4,4,0,0,0,0,0,0,0,5,0,0,0,
0,0,0,0,0,0,0,4,4,4,4,0,0,0,0,0,0,0,0,0,4,4,4,4,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,
4,4,4,4,4,4,4,0,0,0,0,0,4,4,4,4,4,4,4,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,4,4,4,4,4,4,
4,4,4,0,0,3,0,4,4,4,4,4,4,4,0,0,0,0,0,5,0,0,0,4,4,4,4,0,0,4,4,4,4,4,4,4,4,0,0,0,
0,0,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,0,0,4,4,4,4,4,4,4,4,4,0,0,0,4,4,4,4,
4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,4,4,0,
0,0,0,0,0,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
As I said, what is supposed to be outputted is the string that is directly passed into File.WriteAllText.
Am I missing something ? I don't understand what i'm doing wrong. It seems to be working sometimes, but with other string it does not. I can find no relation between the sequences that works and those that do not.
Here is the whole code, it's a simple program that read a bitmap and output the sequence depending on the pixel. It's badly & quickly written but it's supposed to work, i see no reason it shouldn't.
class Program
{
static void Main(string[] args)
{
Console.WriteLine(args[0]);
Bitmap Map = new Bitmap(args[0]);
var MapRGB = Map.Clone(new Rectangle(0, 0, Map.Width, Map.Height), PixelFormat.Format32bppRgb);
int height = Map.Height;
int widht = Map.Width;
string MapText = height.ToString() + "," + widht.ToString() + ",";
for (int h = 0; h < height; h++)
{
for (int w = 0; w < widht; w++)
{
Color currentPixel =
MapRGB.GetPixel(w ,h );
if (currentPixel.ToArgb() == Color.White.ToArgb())
{
MapText = MapText + "0,";
}
if (currentPixel.ToArgb() == Color.Black.ToArgb())
{
MapText = MapText + "1,";
}
if (currentPixel.ToArgb() == Color.Gray.ToArgb())
{
MapText = MapText + "2,";
}
if (currentPixel.ToArgb() == Color.Yellow.ToArgb())
{
MapText = MapText + "3,";
}
if (currentPixel.ToArgb() == Color.Green.ToArgb())
{
MapText = MapText + "4,";
}
if (currentPixel.ToArgb() == Color.Red.ToArgb())
{
MapText = MapText + "5,";
}
Console.Clear();
Console.WriteLine(args[0] + " WROKING " + w.ToString() + " OF " + widht.ToString() + " IN " + h.ToString() + " OF " + height.ToString());
}
}
Console.Clear();
Console.Write(MapText);
System.IO.File.WriteAllText(Environment.CurrentDirectory + "/Map.bwn", MapText);
Console.ReadKey();
}
}
Not absolutely sure but could be an encoding issue. Use the other overload File.WriteAllText(String, String, Encoding) which takes a encoding type as argument like
File.WriteAllText(filePath, stringMessage, Encoding.UTF8);

why does it appear a blank space between to string concatened c#

public string completeHour(string theTime)
{
string total="";
string[] timeArray = theTime.Split(new[] { ":" }, StringSplitOptions.None);
string h = timeArray[0];
string i = timeArray[1];
string j = timeArray[2];
MessageBox.Show(h + "+" + i + "+" + j);
if (h == " " || i == " " || j == " ")
{
if (h == " ")
{
h = "00";
total = (String.Concat("00",theTime)).Trim();
MessageBox.Show(total);
}
else if (i == " ")
{
i = "00";
total = timeArray[0] + i + timeArray[2];
//MessageBox.Show("m-=" + total);
}
//else if (j == "")
//{
// j = "00";
// theTime = timeArray[0] + timeArray[1] + j;
// MessageBox.Show("s-=" + theTime);
//}
}
return total;
}
Why total is 00 :52:04 (for instance) and not 00:52:04 that was supposed to be?
If you'd like to make sure there are no leading or trailing white characters, you could call
string h = timeArray[0].Trim();
And then instead of checking the value against " ", you could compare it to String.Empty or call h.IsNullOrEmpty().
However I'd strongly recommend you to use simpler approach, using a DateTime object.
DateTime timeObject;
DateTime.TryParse(theTime, out timeObject);
and then just work with Hour, Minute and Second properties. This way you get away from custom parsing and make your code more object-oriented, thus easier to read, instead of juggling multiple string objects.
Best way to avoid this is using Trim() when assigning value to total in following two lines:
total = (String.Concat("00",theTime.Trim())).Trim();
.
.
.
total = timeArray[0].trim() + i + timeArray[2].Trim();
Although I was using a MaskedTextBox I didn't define a custom mask so, anywhere (I think) the system assumed that 'theTime' was the type of DateTime.
So, the result of String.Concat("00",theTime) was '00 :32:99', for instance.
I´ve solved it by using the variables h, i and j instead of theTime.
Using a DateTime variable was not appropriated because I want to allow the user to insert NULL values for the hours or for the minutes.

Better way of doing it - GetFiles - c#

I'm trying to get all files in a directory but I want them associated with numbers. Now, I have this:
string[] ficheiro = Directory.GetFiles(#"C:\Users\David\Documents\Jogos\Jogos de emuladores\Roms GB\", "*.gba");
{
Console.WriteLine ("F1" + " - " + Path.GetFileNameWithoutExtension (ficheiro[0]));
}
Console.ReadKey ();
When I reach 10 files I will have a shortcut to flip a page to get more files (10 per page). I will list all files by hand. Like this:
Console.WriteLine ("F2" + " - " + Path.GetFileNameWithoutExtension (ficheiro[1]));
Console.WriteLine ("F3" + " - " + Path.GetFileNameWithoutExtension (ficheiro[2]));
Is there a better way of doing it?
You need to use a loop. You cannot do all of them "by hand" because you do not necessarily know how many there are.
var files = Directory.GetFiles(#"C:\Your\Directory\Path", "*.gba");
var count = 0;
foreach (var file in files)
{
if (count % 10 == 0 && count != 0)
{
Console.ReadLine();
}
count++;
Console.WriteLine("F{0} - {1}", count, Path.GetFileNameWithoutExtension(file));
}
Console.ReadLine();
You can iterate through the array with a for-loop :
string[] ficheiros = Directory.GetFiles(#"C:\Users\David\Documents\Jogos\Jogos de emuladores\Roms GB\", "*.gba");
for (int i = 0; i < ficheiros.Length; i++)
{
Console.WriteLine("F{0} - {1}", i + 1, Path.GetFileNameWithoutExtension(ficheiros[i]));
}
Console.ReadKey();
The key is to identify the repeating part and extract a pattern from it :
//only these changed V V
Console.WriteLine ("F2" + " - " + Path.GetFileNameWithoutExtension (ficheiro[1]));
Console.WriteLine ("F3" + " - " + Path.GetFileNameWithoutExtension (ficheiro[2]));
// just replace them and put it inside an appropriate loop, in this case a for-loop
for(int i = 0; i < ficheiro.Length; i++)
Console.WriteLine ("F" + (i+1) + " - " + Path.GetFileNameWithoutExtension (ficheiro[i]));
int i = 0;
var ficheiro = from s in Directory.GetFiles(#"C:\temp\", "*.*")
select ("F"+ i++ + "-" + s);

Loading multiple files Exception error C#

I am making the game minesweeper and I am trying to implement a highScores feature. I am trying to load 3 different files (each one holds the high scores for each of the 3 difficulty settings) into 3 different richTextBox's. When I run the app and click the 'high scores' tab from the menu strip it works the first time. However if I play a game and then try to access the high scores form I get an Exception error -
An unhandled exception of type 'System.IO.IOException' occurred in
mscorlib.dll
Additional information: The process cannot access the file
'C:\Users\jzcon_000\Copy\Visual
Studio\Projects\Assignment1\Assignment1\bin\Debug\highScoresMed.txt'
because it is being used by another process
This is where the call is made
private void highScoresToolStripMenuItem_Click(object sender, EventArgs e)
{
Minesweeper.HighSc highScore = new Minesweeper.HighSc();
highScore.read();
highScore.Show();
}
This is the method in my HighSc class
public void read()
{
StreamReader readerE = File.OpenText("highScoresEasy.txt");
StreamReader readerM = File.OpenText("highScoresMed.txt");
StreamReader readerH = File.OpenText("highScoresHard.txt");
if (readerE != null)
{
string readEasy = File.ReadAllText("highScoresEasy.txt");
richTextBox1.Text = readEasy;
}
readerE.Close();
if (readerM != null)
{
string readMed = File.ReadAllText("highScoresMed.txt");
richTextBox2.Text = readMed;
}
readerM.Close();
if (readerH != null)
{
string readHard = File.ReadAllText("highScoresHard.txt");
richTextBox3.Text = readHard;
}
readerH.Close();
}
Heres the save high scores class
namespace Minesweeper
{
class Save
{
int diff, hr, min, sec;
string player;
public Save(int difficulty, int hour, int minute, int second, string playerN)
{
diff = difficulty;
hr = hour;
min = minute;
sec = second;
player = playerN;
}
public void save()
{
StreamWriter writerEasy = new StreamWriter("highScoresEasy.txt", true);
StreamWriter writerMed = new StreamWriter("highScoresMed.txt", true);
StreamWriter writerHard = new StreamWriter("highScoresHard.txt", true);
if (diff == 1)
{
writerEasy.WriteLine("Time: " + hr + ":" + min + ":" + sec + " " + "Name: " + player);
writerEasy.Close();
}
else if (diff == 2)
{
writerMed.WriteLine("Time: " + hr + ":" + min + ":" + sec + " " + "Name: " + player);
writerMed.Close();
}
else if (diff == 3)
{
writerHard.WriteLine("Time: " + hr + ":" + min + ":" + sec + " " + "Name: " + player);
writerHard.Close();
}
}
}
}
So when you have the difficulty level set to 1 and then save, you open the StreamWriters for both the level2 and level3 but never close them.
This could only mean that when you try to load the highscore for these two levels you will find your files locked by your previous save.
You should change your Save method to open only the required file
public void save()
{
if (diff == 1)
{
using(StreamWriter writerEasy = new StreamWriter("highScoresEasy.txt", true))
{
writerEasy.WriteLine("Time: " + hr + ":" + min + ":" + sec + " " + "Name: " + player);
}
}
else if (diff == 2)
....
else if (diff == 3)
....
I suggest also to use the using statement in your reading method to be sure that also in case of exceptions the stream are correctly disposed

create one time reference for various sample rates per file

My program reads in multiple files that contain time/value pairs sampled at different rates. I'm trying to use the file with the highest sample rate as the time scale for all sampled rates and output one master file with the unique time values from the highest sample rate file.
Each file contains time/values pairs like:
1,58
1.5,90
2,154
2.5,34
Here is my code so far:
public void ReadAndWrite(string[] fileNames)
{
var stopwatch = Stopwatch.StartNew();
List<StreamReader> readers = fileNames.Select(f => new StreamReader(f)).ToList();
try
{
using (StreamWriter writer = new StreamWriter(tbxOutputFile.Text))
{
string line = null;
// For each measurement in max measurements
for (int measNum = 0; measNum < numOfRows; measNum++)
{
// For each file's reader
for (int i = 0; i < readers.Count; i++)
{
// If line contains something, then add it to line
if ((line = readers[i].ReadLine()) != null)
{
// Process line and then write it to file
line = ProcessLine(line);
writer.Write(line);
}
else
{
writer.Write("");
}
// If it's not the last column, add delimiter
if (i < readers.Count - 1)
writer.Write(",");
}
writer.WriteLine();
// Update labels
int val = ((measNum + 1) * 100) / numOfRows;
string newText = Convert.ToString("Progress: " + val + "% " + " " + "Measurement #: " + (measNum + 1)
+ " out of " + numOfRows); // running on worker thread
this.Invoke((MethodInvoker)delegate
{
// runs on UI thread
lblStatus.Text = newText;
progressBar1.Value = val;
});
}
}
}
catch (Exception)
{
throw;
}
finally
{
foreach (var reader in readers)
{
reader.Close();
}
}
MessageBox.Show("File successfully created! " + '\n' + "Elapsed time: " +
(stopwatch.ElapsedMilliseconds/1000) + " seconds", "Processing Complete");
}
I came up with the pseudo code below (currentTime is the time from each file and uniqueTime is from an array that reads in each time from the highest sampled file):
// if time value from individual file is same as uniqueTime
if currentTime == uniqueTime
{
valueToWrite = curr_value // write the current value
}
else // currentTime is not same as uniqueTime
{
valueToWrite = prev_value // write the previous value
}
timeToWrite = uniqueTime // always write the uniqueTime
What is the best way to execute this pseudo code to make a unique time reference for all the various sample rates? Sorry if my question is confusing, I can elaborate more if need be.
To be clear about this, you do not want the values at the specific time they occurred, but you want to display one value for each source at each timepoint that the highest sampled source has?
That should be pretty straightforward. In pseudocode:
foreach (ValuePair val in highSampleRateValues) {
var aggregatedTimePointData;
aggregatedTimePointData.Add(val.Time, val.Value);
foreach (ValuePair val2 in lowSampleRateValues) {
var value = DetermineLatestEntryBackwardFrom(val.Time);
aggregatedTimePointData.Add(value);
}
}
This way, the sample rate of the higher density sampled signal serves as a clock, but you will have inaccuracies since the values from the other sources are only close, but not exactly on the timepoint of their recording. If you want those inaccuracies reduced, choose a higher sample rate and do the same thing. You can get as close to the actual timepoints as you want.

Categories