HI guys,
I only started c# recently so I'm not 100% familiar with it's syntax yet and I got into a problem. I'd like to write the current time into a filename. I'm using the following code:
DateTime now = DateTime.now;
string dateString = string.Format(#"Z:\test\{0}.bmp",now.ToString("s"));
bitmap.Save(dateString);
Now this gives me a can't access filepath error. Apparently it has something to do with the ":" characters at the time part (at least when I give a now.ToString("d") ) it saves fine.
Any idea whats causing this? Thanks.
The "s" format will create a filename of something like:
2009-06-15T13:45:30.bmp
That's just not a valid filename, due to the colon. Either replace the colon with another character after calling ToString, or use a different format.
Note that "d" won't always work either, as it can include "/" in the name, depending on the culture.
Personally I'd suggest something like "yyyyMMdd-HHmmss" which will give you something like
20090615-134530.bmp
Regardless of the code, the Windows filesystems won't allow the use of a colon (or several other "special" characters) in a filename. So the issue is happening at the OS level, not in your code.
You'll want to strip out those characters and/or format the timestamp differently to use it as a filename.
Some characters are not valid in filenames on Windows - See this link. This is not related to c#.
That is caused by the Windows file system, which disallows :'s in file names.
':' are invalid characters for naming a file. You'll need to determine some other valid character to substitute for ':' before attempting to save the file.
public static class SPStringUtils
{
public static string MakeFilename(this DateTime dt)
{
return dt.ToString("yyyyMMdd-HHmmss");
}
public static string MakeFilename(this DateTime dt, string format)
{
return string.Format(format, MakeFilename(Now));
}
}
...
Console.WriteLine(Now.MakeFilename(#"c:\logs\log{0}.log");
There can't be no ':' in a file name, that's why.
Related
I need to create some log files with a name like this:
HH:mm_dd-MM-yyyy.log
I've tried to convert DateTime & DateTime.Now like this but the compiler encounters the next error:
The given path's format is not supported.
Code i've tried:
#1
var currentDateTime = DateTime.Now;
string format = "HH:mm_dd-MM-yyyy";
string datetime = currentDateTime.ToString(format);
File.Create("Log/GameLog/"+datetime+".log");
#2
string datetime = DateTime.Now.ToString("HH:mm_dd-MM-yyyy");
File.Create("Log/GameLog/"+datetime+".log");
In this couple of cases the same error was raised by the compiler...
So in the end, my question is, how can i use datetime as a file name?
The problem is the : character, you can't use that in a file name
DateTime.Now.ToString("yyyy-dd-M--HH-mm-ss");
Widows Operating System does not allow following special characters in filename.
/ \ : * ? " < > |
so you need to Replace colon : with some other character (either with _ or with -)
Try This:
string datetime = DateTime.Now.ToString("HH_mm_dd-MM-yyyy");
try removing some of the characters you are returning with format and then add them in on at a time to see which is causing the problem.
My guess is it maybe the : character causing you a problem
also check this post which may help.
How to remove illegal characters from path and filenames?
regards
I am creating C# Windows Form that retrieves files from shared drives as email attachments. I am trying to automate the file retrieval process, but the filepaths available to me vary according to the date. For example:
V:\....\Dec-03\filename12-3-2013.xml
J:\.....\December\filename12-4-2013
I have the filepath stored as string from a textbox, but since the path varies slightly day-to-day, I've been trying to figure out how automate this process. In the past I've used VBA code where I've concatenated method calls into the string like this
"..." & Day(Date) & "..."
(I replaced the ampersand with the plus sign of course for C#)
But this just gets me an illegal characters in path Argument exception.
I am using a check for filedate and taking a a specific filepath through a textbox. I want particular files that are being updated in monthly folders and the filename contains a date. I want to grab the ones with today's date or yesterday's date, but some have no date in the filename or directory at all. Since there isn't a lot of consistency, I would love to enter code
"+ DateTime.Now.ToString() +"
in the textbox per individual filepath as I load them via the form and have the program execute like I've done with some VBA code, but I get Illegal characters with the double quotes in the middle of a filepath. Is there some work around or will I need to create fixes for every particular pattern?
Use System.IO.Path.Combine(...) to handle chaining directories together (it takes care of extra slashes for you). In your combine, use String.Format(SomeFormatString, token1value, toke2value, etc.) to give you the name you were wanting.
C# uses + to append strings instead of & in older VB.
"My Date: " + DateTime.Now.ToString("MM/dd/yyyy")
An example of this with the String.Format I showed above would be
string.Format("My Date: {0}", DateTime.Now.ToString("MM/dd/yyyy"))
If I'm following what you're saying about Day(Date), you might try some thing like this in C#:
MyObject.SomeMethod("some string " + dateValue.ToString("ddd") + " more string data");
Where dateValue is a DateTime object and the "ddd" parameter tells the ToString method to return a three character abbreviation of the day of the week (e.g. 'Wed').
For more information on using ToString with DateTime objects to extract various parts of the date, see
http://msdn.microsoft.com/en-us/library/bb762911(v=vs.100).aspx?cs-save-lang=1&cs-lang=csharp#code-snippet-2
The ToString overload of the DateTime structure will allow you to format a date as the Month name, etc.
var x = DateTime.Today.ToString("MMMM"); // December
You can include other characters in the format string as well, for example to get Dec-19 you can use:
var x = DateTime.Today.ToString("MMM-dd"); // Dec-19
TyCobb's answer covers combining the formatted date into a path using Path.Combine (which I generally recommend).
You can also use String.Format to insert a formatted value into a string, which is often easier to read and leads to fewer mistakes. For example, to generate your first example, you could use the following:
var path =
String.Format("V:....\{0:MMM-dd}\filename{0:M-d-yyyy}.xml", DateTime.Today);
We have a requirement to display bank routing/account data that is masked with asterisks, except for the last 4 numbers. It seemed simple enough until I found this in unit testing:
string.Format("{0:****1234}",61101234)
is properly displayed as: "****1234"
but
string.Format("{0:****0052}",16000052)
is incorrectly displayed (due to the zeros??): "****1600005252""
If you use the following in C# it works correctly, but I am unable to use this because DevExpress automatically wraps it with "{0: ... }" when you set the displayformat without the curly brackets:
string.Format("****0052",16000052)
Can anyone think of a way to get this format to work properly inside curly brackets (with the full 8 digit number passed in)?
UPDATE: The string.format above is only a way of testing the problem I am trying to solve. It is not the finished code. I have to pass to DevExpress a string format inside braces in order for the routing number to be formatted correctly.
It's a shame that you haven't included the code which is building the format string. It's very odd to have the format string depend on the data in the way that it looks like you have.
I would not try to do this in a format string; instead, I'd write a method to convert the credit card number into an "obscured" string form, quite possibly just using Substring and string concatenation. For example:
public static string ObscureFirstFourCharacters(string input)
{
// TODO: Argument validation
return "****" + input.Substring(4);
}
(It's not clear what the data type of your credit card number is. If it's a numeric type and you need to convert it to a string first, you need to be careful to end up with a fixed-size string, left-padded with zeroes.)
I think you are looking for something like this:
string.Format("{0:****0000}", 16000052);
But I have not seen that with the * inline like that. Without knowing better I probably would have done:
string.Format("{0}{1}", "****", str.Substring(str.Length-4, 4);
Or even dropping the format call if I knew the length.
These approaches are worthwhile to look through: Mask out part first 12 characters of string with *?
As you are alluding to in the comments, this should also work:
string.Format("{0:****####}", 16000052);
The difference is using the 0's will display a zero if no digit is present, # will not. Should be moot in your situation.
If for some reason you want to print the literal zeros, use this:
string.Format("{0:****\0\052}", 16000052);
But note that this is not doing anything with your input at all.
i have a string that looks like this:
"/dir/location/test-load-ABCD.p"
and i need to parse out "ABCD" (where ABCD will be a different value every day)
The only things that i know that will always be consistent (to use for the logic for parsing) are:
There will always be be a ".p" after the value
There will always be a "test-load-" before the value.
The things i thought of was somehow grab everything past the last "/" and then remove the last 2 characters (to take case of the ".p" and then to do a
.Replace("test-load-", "")
but it felt kind of hacky so i wanted to see if people had any suggestions on a more elegant solution.
You can use a regex:
static readonly Regex parser = new Regex(#"/test-load-(.+)\.p");
string part = parser.Match(str).Groups[1].Value;
For added resilience, replace .+ with a character class containing only the characters that can appear in that part.
Bonus:
You probably next want
DateTime date = DateTime.ParseExact(part, "yyyy-MM-dd", CultureInfo.InvariantCulture);
Since this is a file name, use the file name parsing facility offered by the framework:
var fileName = System.IO.Path.GetFileNameWithoutExtension("/dir/location/test-load-ABCD.p");
string result = fileName.Replace("test-load-", "");
A “less hacky” solution than using Replace would be the use of regular expressions to capture the solution but I think this would be overkill in this case.
string input = "/dir/location/test-load-ABCD.p";
Regex.Match(input, #"test-load-([a-zA-Z]+)\.p$").Groups[1].Value
I'm currently working on a web service that retrieves an XML message, archives it and then processes it further. The archive folder is read from the Web.config. This is what the archive method looks like
private void Archive(System.Xml.XmlDocument xmlDocument)
{
try
{
string directory = System.Configuration.ConfigurationManager.AppSettings.Get("ArchivePath");
ParseMessage(xmlDocument);
directory = string.Format(#"{0}\{1}\{2}", directory, _senderService, DateTime.Now.ToString("MMMyyyy"));
System.IO.Directory.CreateDirectory(directory);
string Id = _messageID;
string senderService = _senderService;
xmlDocument.Save(directory + #"\" + DateTime.Now.ToString("yyyyMMdd_") + Id + "_" + System.Guid.NewGuid().ToString().Substring(0, 13) + ".xml");
}
The path structure I retrieve is C:\Program Files\Subfolder\Subfolder. In the development, QA, UAT and PRD environments everything works fine. But on another machine I now need to install the web service on (which I cannot debug, unfortunately), the directory string is 'C:Files'.
Just to be sure I double checked the .NET version on the different machines (I thought perhaps the usage of # before a string was version-dependent); all machines use 2.0.50727.
Does anyone recognize this problem?
Thanks in advance!
EDIT: I see the # before the directory variable has caused some confusion regarding the question I asked. It was not about that # (in fact, that should not have been there. I have removed it).
My question (rephrased) is:
when you place an # before a quoted string, like #"c:\folder\subfolder", it ensures that the backslashes are not interpreted as escape characters, right? What could be the cause of it working on one machine, but not working on another?
(I do agree with the answers stating to use Path.Combine by the way. I'm just curious what causes this inconsistent behaviour)
You could try using Path.Combine() instead of String.Format(). A good example is here.
When a value is pulled from the configuration file, it is automatically escaped properly. The '#' symbol on your directory variable name is not setting it to be 'explicit' - it's tell the compiler that it is a named parameter. For example:
public void (string[] args)
{
int length = args.Length;
length = #args.Length; // Same thing!
}
The '#' operator on a variable name means to not treat that symbol as a reserved word. It allows you to make variable names with the same name as a keyword:
public static void Foo(object #class)
{
//#class exists here, even though class is a reserved keyword!
}
In addition, if the value it is getting is 'C:Files', then that is invalid, as it is missing a '\'. 'C:\Files' would be valid.
Use Path.Combine(), for instance:
strFilename = CombinePaths(directory, _senderService) + DateTime.Now.ToString("MMMyyyy");
From your question I think that you've treated:
#directory
As if it performed the same function as:
#"c:\myfolder\"
The difference is that the first example allows you to use a reserved word as a variable name, like #class (don't get into the habit of using it) and the second example allows the string to contain unescaped characters such as .