I have a file on which I want to replace the dates but I don't know what dates are on it and I want to do generic code for me to use the same executable for other files.
I put all content of the file in a string and I want to replace all dates with format dd/mm/yyyy (ex: 19/12/2011) with the actual date (20/12/2011).
How can I do that?
Code so far:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace ReplaceDates
{
class Program
{
static int Main(string[] args)
{
string FileIn = retreiveArgument(args, "i");
int AddDays = Int32.Parse(retreiveArgument(args, "d"));
string date = (System.DateTime.Now).AddDays(AddDays).ToString("dd/MM/yyyy");
string content = "", date2replace = "";
if (File.Exists(FileIn))
{
File.Copy(FileIn, FileIn + ".bkp", true);
try
{
content = File.ReadAllText(FileIn);
// here is what I need to do
}
catch (Exception)
{
Console.WriteLine("Error replacing dates in " + FileIn + ".");
return 0;
}
try
{
File.WriteAllText(FileIn, content);
Console.WriteLine("Dates replaced in " + FileIn + ".");
return 0;
}
catch (Exception)
{
Console.WriteLine("Couldn't write the file " + FileIn);
return 2;
}
}
else
{
Console.WriteLine("File " + FileIn + " does not exist.");
return 1;
}
}
private static string retreiveArgument(string[] argument, string argumentName)
{
for (int i = 0; i < argument.Length; i++)
{
if (argument[i].ToLower().Equals("-h") || argument[i].ToLower().Equals("help") || argument[i].ToLower().Equals("-help") || argument[i].Equals("?") || argument[i].Equals("-?"))
{
Console.WriteLine("Usage : ");
Console.WriteLine("ReplaceDates.exe -i [Input File] -d [Addition]");
Console.WriteLine("[Input File] -> Complete path to the file.");
Console.WriteLine("[Addition] -> Adds the specified value in days to the actual date.");
Console.WriteLine();
Console.WriteLine("This executable replaces the data from the input file.");
}
else
{
if (argument[i].Equals("-" + argumentName))
{
return argument[i + 1].Trim();
}
}
}
return "";
}
}
}
Here's a solution using a MatchEvaluator. Tweak the regular expression if desired;
string UpdateDates(string input)
{
return Regex.Replace(input, #"\d{2}/\d{2}/\d{4}", m => DateTime.Now.ToString("dd/MM/yyyy"));
}
you can use a regex for that http://www.regular-expressions.info/dates.html
Use another file that contains the layout of the original file but in the dates that you need to replace put another string, something like "DD/MM/YYYY".
Now, you simply need to open the layout file, read all content, replace the "DD/MM/YYYY" for the date you want and voilá :)
Related
I'm trying to make a program that automatically copies and sorts the pictures from an SD card to an external hard drive using Metadata Extractor 2.4.3
I don't seem to find any prolem but every time I run the code, an unhandled exception prompts up.
Here's the error:
Unhandled Exception: MetadataExtractor.ImageProcessingException: File format could not be determined
at MetadataExtractor.ImageMetadataReader.ReadMetadata(Stream stream)
at MetadataExtractor.ImageMetadataReader.ReadMetadata(String filePath)
at file_sorter.File..ctor(String filepath) in
C:\Users\ropra\Documents\file_sorter\file_sorter\File.cs:line 27
at file_sorter.Program.Main(String[] args) in
C:\Users\ropra\Documents\file_sorter\file_sorter\Program.cs:line 27
Here's the code:
Program.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MetadataExtractor;
namespace file_sorter
{
class Program
{
static void Main(string[] args)
{
// Define paths
string sandisk = #"Z:/Images/RAW";
string sd = #"Y:/DCIM/100_FUJI";
// Count elements in sd
string[] photoPaths = System.IO.Directory.GetFiles(sd);
Console.WriteLine("Counting elements in SD card...");
// Create object array
File[] photos = new File[photoPaths.Count()];
for (int i = 0; i < photos.Count(); i++)
{
photos[i] = new File(photoPaths[i]);
}
// Create tree and copy files
foreach (var item in photos)
{
string fileName = item.filename;
string sourcePath = item.sourcepath;
string targetPath = sandisk + "/" + item.year + "/" + item.month + "/" + item.day;
string sourceFile = System.IO.Path.Combine(sourcePath, fileName);
string destFile = System.IO.Path.Combine(targetPath, fileName);
Console.WriteLine("Now copying: {0} into {1}", fileName, targetPath);
System.IO.Directory.CreateDirectory(targetPath);
System.IO.File.Copy(sourceFile, destFile, true);
}
}
}
}
File.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MetadataExtractor;
namespace file_sorter
{
public class File
{
public string filename;
public string path;
public string year;
public string month;
public string day;
public string sourcepath;
public File(string filepath)
{
path = filepath;
filename = path.Substring(path.LastIndexOf("\\") + 1);
sourcepath = path.Substring(0, path.LastIndexOf("\\"));
string rawDate = "";
var metadata = ImageMetadataReader.ReadMetadata(path);
for (int i = 0; i < metadata.Count(); i++)
{
for (int j = 0; j < metadata[i].TagCount; j++)
{
if (metadata[i].Name == "Exif IFD0" && metadata[i].Tags[j].Name == "Date/Time")
{
rawDate = metadata[i].Tags[j].Description;
}
}
}
int separator = rawDate.IndexOf(":");
year = rawDate.Substring(0, separator);
string sub = rawDate.Substring(separator + 1);
separator = sub.IndexOf(":");
month = sub.Substring(0, separator);
sub = sub.Substring(separator + 1);
separator = sub.IndexOf(" ");
day = sub.Substring(0, separator);
}
public void ShowFormatedDate()
{
Console.WriteLine("Path: {0}", path);
Console.WriteLine("File: {0}", filename);
Console.WriteLine("Dir: {0}", sourcepath);
Console.WriteLine("Year: {0}", year);
Console.WriteLine("Month: {0}", month);
Console.WriteLine("Day: {0}", day);
Console.WriteLine("");
}
}
}
Thank you in advance.
OK, so having given up and sorting all files manually, I came across an .xml file containing the metadata of a single .RAF file, I'm guessing my camera put it there.
This program does not handle MetadataExtractor non-supported files, hence the problem.
ImageProcessingException: File format could not be determined
This exception means that the library didn't identify the file it was given as anything it knows how to read. For example, if you give a text file to the library, you will see this exception.
Perhaps you could catch this exception type and use a different code path for such files.
Struggling with a C# Component. What I am trying to do is take a column that is ntext in my input source which is delimited with pipes, and then write the array to a text file. When I run my component my output looks like this:
DealerID,StockNumber,Option
161552,P1427,Microsoft.SqlServer.Dts.Pipeline.BlobColumn
Ive been working with the GetBlobData method and im struggling with it. Any help with be greatly appreciated! Here is the full script:
public override void Input0_ProcessInputRow(Input0Buffer Row)
{
string vehicleoptionsdelimited = Row.Options.ToString();
//string OptionBlob = Row.Options.GetBlobData(int ;
//string vehicleoptionsdelimited = System.Text.Encoding.GetEncoding(Row.Options.ColumnInfo.CodePage).GetChars(OptionBlob);
string[] option = vehicleoptionsdelimited.Split('|');
string path = #"C:\Users\User\Desktop\Local_DS_CSVs\";
string[] headerline =
{
"DealerID" + "," + "StockNumber" + "," + "Option"
};
System.IO.File.WriteAllLines(path + "OptionInput.txt", headerline);
using (System.IO.StreamWriter file = new System.IO.StreamWriter(path + "OptionInput.txt", true))
{
foreach (string s in option)
{
file.WriteLine(Row.DealerID.ToString() + "," + Row.StockNumber.ToString() + "," + s);
}
}
Try using
BlobToString(Row.Options)
using this function:
private string BlobToString(BlobColumn blob)
{
string result = "";
try
{
if (blob != null)
{
result = System.Text.Encoding.Unicode.GetString(blob.GetBlobData(0, Convert.ToInt32(blob.Length)));
}
}
catch (Exception ex)
{
result = ex.Message;
}
return result;
}
Adapted from:
http://mscrmtech.com/201001257/converting-microsoftsqlserverdtspipelineblobcolumn-to-string-in-ssis-using-c
Another very easy solution to this problem, because it is a total PITA, is to route the error output to a derived column component and cast your blob data to a to a STR or WSTR as a new column.
Route the output of that to your script component and the data will come in as an additional column on the pipeline ready for you to parse.
This will probably only work if your data is less than 8000 characters long.
namespace FileOperation
{
class FileOperation_details
{
static void Main(string[] args)
{
FileStream fileOperation = new FileStream("imp.txt",FileMode.Open,FileAccess.ReadWrite);
int i;
//for ( i = 0;i<=10;i++)
//{
// fileOperation.WriteByte((byte)i);
//}
fileOperation.Position = 0;
for(i =0;i<=10;i++)
{
Console.Write(Convert.ToString(fileOperation.ReadByte()) + "");
}
fileOperation.Close();
Console.ReadKey();
}
}
}
but am getting output as ascii values of string .ie my data in file is "welcome to india " but output is ascii values of each each character.so please help me
You can use this code :
string str = ((char)fileOperation.ReadByte()).ToString();
Console.Write(str + "");
I am trying to develop upload file function with security as my programming instructor asked me to do. I implemented it in such a way that it will check the size, file format and the existence of the file. The logic was working well except for checking the existence of the file. For example, when I tried to upload a file which is already existed, I will not get a message telling me that the file is already existed and I don't know why it is not working.
protected void UploadFile(object sender, EventArgs e)
{
if(FileUpload1.HasFile)
try
{
string[] validTypes = { "bmp", "gif"};
string ext = System.IO.Path.GetExtension(FileUpload1.PostedFile.FileName);
if (size < limit)
{
for (int i = 0; i < validTypes.Length; i++)
{
if (ext == "." + validTypes[i])
{
string path = #"~\Images\";
string comPath = Server.MapPath(path + "\\" + FileUpload1.FileName);
if (!File.Exists(comPath))
{
FileUpload1.PostedFile.SaveAs(comPath);
Label1.Text = "File uploaded";
}
else
{
Label1.Text = "Existed";
}
}
else
{
Label1.Text = "Invalid File." + string.Join(",", validTypes);
}
}
}
else
{
Label2.ForeColor = System.Drawing.Color.Red;
Label2.Text = "file is heavy";
}
}
catch (Exception ex)
{
Label2.Text = "The file could not be uploaded. The following error occured: " + ex.Message;
}
}
When I debugged the code, I found that it will execute the else statement, but instead of displaying it to the user, it will display the message in the outer else statement which is "Invalid File.". Why?
if (ext == "." + validTypes[i])
{
string path = #"~\Images\";
string comPath = Server.MapPath(path + "\\" + FileUpload1.FileName);
if (!File.Exists(comPath))
{
FileUpload1.PostedFile.SaveAs(comPath);
Label1.Text = "File uploaded";
}
else
{
Label1.Text = "Existed";
}
}
else
{
Label1.Text = "Invalid File." + string.Join(",", validTypes);
}
Also, my instructor told me that the following line causes a vulnerability called path traversal.
string path = #"~\Images\";
So how to prevent this security hole? ?Any ideas?
There is logical problem in you code.In the block
for (int i = 0; i < validTypes.Length; i++)
It will always run two time for each file.
What you can do you take a Boolean variable at set it to false.
Go inside the loop and if file found set boolean to true and use break statement.
At the end of loop check for the Boolean value and code accordingly.
Edit-1
Rather than looping through the array you can use like this
string[] stringArray = { "text1", "text2", "text3", "text4" };
string value = "text3";
int pos = Array.IndexOf(stringArray, value);
if (pos >- 1)
{
// the array contains the string and the pos variable
// will have its position in the array
}
In your case
string[] validTypes = { "bmp", "gif"};
string ext = System.IO.Path.GetExtension(FileUpload1.PostedFile.FileName);
int pos = Array.IndexOf(validTypes , ext );
if(pos>=0)
{
string path = #"~\Images\";
string comPath = Server.MapPath(path + "\\" + FileUpload1.FileName);
if (!File.Exists(comPath))
{
FileUpload1.PostedFile.SaveAs(comPath);
Label1.Text = "File uploaded";
}
else
{
Label1.Text = "Existed";
}
}
else
{
Label1.Text = "Invalid File." + string.Join(",", validTypes);
}
I have a windows service , that takes files with metadata(FIDEF) and corresponding video file and , translates the XML(FIDEF) using XSLT .
I get the file directory listing for FIDEF's and if a video file of the same name exists it translates it. That works ok , but it is on a timer to search every minute. I am trying to handle situations where the same file name enters the input directory but is already in the output directory. I just have it changing the output name to (copy) thus if another file enters i should get (copy)(copy).mov but the service won't start with filenames of the same directory already in the output , it works once and then does not seem to pick up any new files.
Any Help would be great as I have tried a few things with no good results. I believe its the renaming methods, but I've put most of the code up in case its a clean up issue or something else.
(forgive some of the names just trying different things).
private void getFileList()
{
//Get FILE LIST FROM Directory
try
{
// Process Each String/File In Directory
string result;
//string filename;
filepaths = null;
filepaths = Directory.GetFiles(path, Filetype);
foreach (string s in filepaths)
{
for (int i = 0; i < filepaths.Length; i++)
{
//Result Returns Video Name
result = Path.GetFileNameWithoutExtension(filepaths[i]);
FileInfo f = new FileInfo(filepaths[i]);
PreformTranslation(f, outputPath + result , result);
}
}
}
catch (Exception e)
{
EventLog.WriteEntry("Error " + e);
}
}
private void MoveVideoFiles(String Input, String Output)
{
File.Move(Input, Output);
}
private string GetUniqueName(string name)
{
//Original Filename
String ValidName = name;
//remove FIDEF from filename
String Justname1 = Path.GetFileNameWithoutExtension(name);
//get .mov extension
String Extension2 = Path.GetExtension(Justname1);
//get filename with NO extensions
String Justname = Path.GetFileNameWithoutExtension(Justname1);
//get .Fidef
String Extension = Path.GetExtension(name);
int cnt = 0;
//string[] FileName = Justname.Split('(');
//string Name = FileName[0];
while (File.Exists(ValidName)==true)
{
ValidName = outputPath + Justname + "(Copy)" + Extension2 + Extension;
cnt++;
}
return ValidName;
}
private string getMovFile(string name)
{
String ValidName = name;
String Ext = Path.GetExtension(name);
String JustName = Path.GetFileNameWithoutExtension(name);
while(File.Exists(ValidName))
{
ValidName = outputPath + JustName + "(Copy)" + Ext;
}
return ValidName;
}
//Preforms the translation requires XSL & FIDEF name.
private void PreformTranslation(FileInfo FileName, String OutputFileName , String result)
{
string FidefName = OutputFileName + ".FIDEF";
String CopyName;
String copyVidName = outputPath + result;
XslCompiledTransform myXslTransform;
myXslTransform = new XslCompiledTransform();
try
{
myXslTransform.Load(XSLname);
}
catch
{
EventLog.WriteEntry("Error in loading XSL");
}
try
{ //only process FIDEF's with corresponding Video file
if (AllFidef == "no")
{
//Check if video exists if yes,
if (File.Exists(path + result))
{
//Check for FIDEF File Already Existing in the Output Directory.
if (File.Exists(FidefName))
{
//Get unique name
CopyName = GetUniqueName(FidefName);
copyVidName= getMovFile(copyVidName);
//Translate and create new FIDEF.
//double checking the file is here
if (File.Exists(outputPath + result))
{
myXslTransform.Transform(FileName.ToString(), CopyName);
File.Delete(FileName.ToString());
MoveVideoFiles(path + result, copyVidName);
}
////Move Video file with Corresponding Name.
}
else
{ //If no duplicate file exsists in Directory just move.
myXslTransform.Transform(FileName.ToString(), OutputFileName + ".FIDEF");
MoveVideoFiles(path + result, outputPath + result);
}
}
}
else
{
//Must have FIDEF extension
//Processes All FIDEFS and moves any video files if found.
myXslTransform.Transform(FileName.ToString(), OutputFileName + ".FIDEF");
if (File.Exists(path + result))
{
MoveVideoFiles(path + result, outputPath + result);
}
}
}
catch (Exception e)
{
EventLog.WriteEntry("Error Transforming " + "FILENAME = " + FileName.ToString()
+ " OUTPUT_FILENAME = " + OutputFileName + "\r\n" +"\r\n"+ e);
}
}
There is a lot wrong with your code. getFileList has the unneeded inner for loop for starters. Get rid of it. Your foreach loop has s, which can replace filepaths[i] from your for loop. Also, don't do outputPath + result to make file paths. Use Path.Combine(outputPath, result) instead, since Path.Combine handles directory characters for you. Also, you need to come up with a better name for getFileList, since that is not what the method does at all. Do not make your method names liars.
I would simply get rid of MoveVideoFiles. The compiler just might too.
GetUniqueName only works if your file name is of the form name.mov.fidef, which I'm assuming it is. You really need better variable names though, otherwise it will be a maintenance nightware later on. I would get rid of the == true in the while loop condition, but that is optional. The assignment inside the while is why your files get overwritten. You always generate the same name (something(Copy).mov.fidef), and as far as I can see, if the file exists, I think you blow the stack looping forever. You need to fix that loop to generate a new name (and don't forget Path.Combine). Maybe something like this (note this is untested):
int copyCount = 0;
while (File.Exists(ValidName))
{
const string CopyName = "(Copy)";
string copyString = copyCount == 0 ? CopyName : (CopyName + "(" + copyCount + ")");
string tempName = Justname + copyString + Extension2 + Extension;
ValidName = Path.Combine(outputPath, tempName);
copyCount++;
}
This generates something(Copy).mov.fidef for the first copy, something(Copy)(2).mov.fidef for the second, and so on. Maybe not what you want, but you can make adjustments.
At this point you have a lot to do. getMovFile looks as though it could use work in the same manner as GetUniqueName. You'll figure it out. Good luck.