How to strip out header from base 64 image in C#? - c#

I have following base 64 image:
var image='data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAA0gA...';
I am using Convert.FromBase64String()to convert this to bytes:
byte[] bytes = Convert.FromBase64String(convert);
But before this, I need to strip out the header of Base 64 string (i.e data:image/png;base64). I am doing this using:
string convert = image.Replace("data:image/png;base64,", string.Empty);
I can write the same statement for all image extensions separately, but these images are very large and scanning through each one seems inefficient.
I searched this solution which uses regular expression in PHP to cut off the header part, while other answer in PHP uses an inbuilt method get_contents.
My Question is: Is there any inbuilt method to get only contents of base 64 url in C#? If not, then is there any generalized way to strip out header for all extensions?

You could try something like this:
string result = Regex.Replace(image, #"^data:image\/[a-zA-Z]+;base64,", string.Empty);
this should catch the different extensions. I haven't tested this though so it might need some fiddling with.

Since you know the only instance of , in the string will be the separator between the preamble and the data, you could do it without regex like this:
string convert = image.Substring(image.IndexOf(",") + 1);

You can use String.Split method.
String[] substrings = image.Split(',');
string header = substrings[0];
string imgData = substrings[1];
byte[] bytes = Convert.FromBase64String(imgData);
UPDATE
Out of curiosity, I wrote a test which method is the fastest.
using System;
using System.Text.RegularExpressions;
namespace StackOwerflow
{
public class Program
{
static public void Main()
{
int repeats = 10000;
string imgStr = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAB0IAAAQ4CAIAA...eXiM/H/wAAAABJRU5ErkJggg=="; //146 kb img file
string r = string.Empty;
var watch = System.Diagnostics.Stopwatch.StartNew();
for (int i = 0; i < repeats; i++)
{
r = RegExMethod(imgStr);
}
watch.Stop();
var elapsedMs = watch.ElapsedMilliseconds;
Console.WriteLine("RegEx time: {0} Ms", elapsedMs);
watch = System.Diagnostics.Stopwatch.StartNew();
for (int i = 0; i < repeats; i++)
{
r = SubStringMethod(imgStr);
}
watch.Stop();
elapsedMs = watch.ElapsedMilliseconds;
Console.WriteLine("SubString time: {0} Ms", elapsedMs);
watch = System.Diagnostics.Stopwatch.StartNew();
for (int i = 0; i < repeats; i++)
{
r = SplitMethod(imgStr);
}
watch.Stop();
elapsedMs = watch.ElapsedMilliseconds;
Console.WriteLine("Split time: {0} Ms", elapsedMs);
Console.ReadKey();
}
public static string RegExMethod(string img)
{
return Regex.Replace(img, #"^data:image\/[a-zA-Z]+;base64,", string.Empty);
}
public static string SubStringMethod(string img)
{
return img.Substring(img.IndexOf(",") + 1);
}
public static string SplitMethod(string img)
{
return img.Split(',')[1];
}
}
}
And for my machine results:
RegEx time: 1022 Ms
SubString time: 1188 Ms
Split time: 5255 Ms
And the winner is RegEx.

Related

Function which takes a string as input and returns an array of strings as follows ABC(abcde) should return [Abcde, aBcde, abCde, abcDe, abcdE]

I am doing this in this way but its remove string previous characters, its out put is (Magic,Agic,Gic,Ic,C) but I want the whole string to be concate before and after.
public string[] Transform(string st)
{
string[] arr = new string[st.Length];
string[] arr1 = new string[st.Length];
for (int x = 0; x < st.Length; x++)
{
arr1[x] = char.ToLower(st[x]) + "".ToString();
}
for (int i = 0; i < st.Length; i++)
{
string st1 = "";
{
st1 = char.ToUpper(st[i]) + st.Substring(i + 1);
}
arr[i] = st1;
}
return arr;
}
You can do this with a single loop:
public static string[] Transform(string str)
{
var strs = new List<string>();
var sb = new StringBuilder();
for (int i = 0; i < str.Length; i++)
{
sb.Clear();
sb.Append(str);
sb[i] = char.ToUpper(str[i]);
strs.Add(sb.ToString());
}
return strs.ToArray();
}
What this does is adds the str to a StringBuilder and then modifies the indexed character with the upper case version of that character. For example, the input abcde will give:
Abcde
aBcde
abCde
abcDe
abcdE
Try it out on DotNetFiddle
If you wanted to get really fancy I'm sure there is some convoluted LINQ that can do the same, but this gives you a basic framework for how it can work.
You forgot to add left part of the string. Try to do like this:
st1 = st.ToLower().Substring + char.ToUpper(st[i]) + st.Substring(i + 1);
Here. This is twice as fast as the method that uses a string builder and a List
public static string[] Transform(string str)
{
var strs = new string [str.Length];
var sb = str.ToCharArray();
char oldCh;
for (int i = 0; i < str.Length; i++)
{
oldCh = sb[i];
sb[i] = char.ToUpper(sb[i]);
strs[i] = new string (sb);
sb[i] = oldCh;
}
return strs;
}
There's no need to clear and keep reading the string to the string builder. We also know the size of the array so that can be allocated at the start.
I wrote an answer for your questions (it's second code snippet), you can modify it for your needs, like changing the return type to string[], or use ToArray() extension method if you wanna stick with it. I think it's more readable this way.
I decided to put a the end little profiler to check CPU usage and memory compared to #Ron Beyer answer.
Here is my first attempt:
public static void Main()
{
var result = Transform("abcde");
result.ToList().ForEach(WriteLine);
}
public static IEnumerable<string> Transform(string str)
{
foreach (var w in str)
{
var split = str.Split(w);
yield return split[0] + char.ToUpper(w) + split[1];
}
}
Result:
Abcde
aBcde
abCde
abcDe
abcdE
Code fiddle https://dotnetfiddle.net/gnsAGX
There is one huge drawback of that code above, it works only if the passed word has unique letters. Therefore "aaaaa" won't produce proper result.
Here is my second successful attempt that seems works with any string input. I used one instance of StringBuilder to decrease the number of objects that would need to be created and manage on one instance, instead of so much copying objects so it's more optimized.
public static void Main()
{
var result = Transform("aaaaa");
result.ToList().ForEach(WriteLine);
}
public static IEnumerable<string> Transform(string str)
{
var result = new StringBuilder(str.ToLower());
for( int i = 0; i < str.Length; i++)
{
result[i] = char.ToUpper(str[i]);
yield return result.ToString();
result[i] = char.ToLower(str[i]);
}
}
Result:
Aaaaa
aAaaa
aaAaa
aaaAa
aaaaA
Code fiddle: https://dotnetfiddle.net/tzhXtP
Measuring execute time and memory uses.
I will use dotnetfiddle.net status panel, to make it easier.
Fiddle has few limitations like time execution of code 10 sec and used memory
besides differences are very significant.
I tested programs with 14 000 repetitions, my code additionally changes the output to array[].
My answer (https://dotnetfiddle.net/1fLVw9)
Last Run: 12:23:09 pm
Compile: 0.046s
Execute: 7.563s
Memory: 16.22Gb
CPU: 7.609s
Compared answer (https://dotnetfiddle.net/Zc88F2)
Compile: 0.031s
Execute: 9.953s
Memory: 16.22Gb
CPU: 9.938s
It slightly reduces the execution time.
Hope this helps!
public static string[] Transform(string str)
{
var strs = new string [str.Length];
var sb = str.ToCharArray();
char oldCh;
for (int i = 0; i < str.Length; i++)
{
oldCh = sb[i];
sb[i] = char.ToUpper(sb[i]);
strs[i] = new string (sb);
sb[i] = oldCh;
}
return strs;
}

C# Concatenate strings or array of chars

I'm facing a problem while developing an application.
Basically,
I have a fixed string, let's say "IHaveADream"
I now want to user to insert another string, for my purpose of a fixed length, and then concatenate every character of the fixed string with every character of the string inserted by the user.
e.g.
The user inserts "ByeBye"
then the output would be:
"IBHyaevBeyAeDream".
How to accomplish this?
I have tried with String.Concat and String.Join, inside a for statement, with no luck.
One memory-efficient option is to use a string builder, since both the original string and the user input could potentially be rather large. As mentioned by Kris, you can initialize your StringBuilder capacity to the combined length of both strings.
void Main()
{
var start = "IHaveADream";
var input = "ByeBye";
var sb = new StringBuilder(start.Length + input.Length);
for (int i = 0; i < start.Length; i++)
{
sb.Append(start[i]);
if (input.Length >= i + 1)
sb.Append(input[i]);
}
sb.ToString().Dump();
}
This only safely accounts for the input string being shorter or equal in length to the starting string. If you had a longer input string, you'd want to take the longer length as the end point for your for loop iteration and check that each array index is not out of bounds.
void Main()
{
var start = "IHaveADream";
var input = "ByeByeByeByeBye";
var sb = new StringBuilder(start.Length + input.Length);
var length = start.Length >= input.Length ? start.Length : input.Length;
for (int i = 0; i < length; i++)
{
if (start.Length >= i + 1)
sb.Append(start[i]);
if (input.Length >= i + 1)
sb.Append(input[i]);
}
sb.ToString().Dump();
}
You can create an array of characters and then re-combine them in the order you want.
char[] chars1 = "IHaveADream".ToCharArray();
char[] chars2 = "ByeBye".ToCharArray();
// you can create a custom algorithm to handle
// different size strings.
char[] c = new char[17];
c[0] = chars1[0];
c[1] = chars2[0];
...
c[13] = chars1[10];
string s = new string(c);
var firstString = "Ihaveadream";
var secondString = "ByeBye";
var stringBuilder = new StringBuilder();
for (int i = 0; i< firstString.Length; i++) {
stringBuilder .Append(str[i]);
if (i < secondString.Length) {
stringBuilder .Append(secondStr[i]);
}
}
var result = stringBuilder.ToString();
If you don't care much about memory usage or perfomance you can just use:
public static string concatStrings(string value, string value2)
{
string result = "";
int i = 0;
for (i = 0; i < Math.Max(value.Length, value2.Length) ; i++)
{
if (i < value.Length) result += value[i].ToString();
if (i < value2.Length) result += value2[i].ToString();
}
return result;
}
Usage:
string conststr = "IHaveADream";
string input = "ByeBye";
var result = ConcatStrings(conststr, input);
Console.WriteLine(result);
Output: IBHyaevBeyAeDream
P.S.
Just checked perfomance of both methods (with strBuilder and simple cancatenation) and it appears to be that both of this methods take same time to execute (if you have just one operation). The main reason for it is that string builder take considerable time to initialize while with use of concatenation we don't need that.
But in case if you have to process something like 1500 strings then it's different story and string builder is more of an option.
For 100 000 method executions it showed 85 (str buld) vs 22 (concat) ms respectively.
My Code

C# Regular Expression filtering characters [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I am having a string in C# and I would like to filter out (throw away) all characters except for digits i.e. 0 to 9. For example if I have a string like "5435%$% r3443_+_+**╥╡←", then the output should be 54353443. How can this be done using regular expression or something else in C#?
Thanks
You don't need regex for this
var newstr = String.Join("", str.Where(c => Char.IsDigit(c)));
Here is some example without regular expressions:
var str = "5435%$% r3443_+_+**╥╡←";
var result = new string(str.Where(o => char.IsDigit(o)).ToArray());
//Or you can make code above slightly more compact, using following syntax:
var result = new string(str.Where(char.IsDigit).ToArray());
Selects from string everything, that is digit-character, and creates new string based on selection.
And speaking about speed.
var sw = new Stopwatch();
var str = "5435%$% r3443_+_+**╥╡←";
sw.Start();
for (int i = 0; i < 100000; i++)
{
var result = new string(str.Where(o => char.IsDigit(o)).ToArray());
}
sw.Stop();
Console.WriteLine(sw.ElapsedMilliseconds); // Takes nearly 107 ms
sw.Reset();
sw.Start();
for (int i = 0; i < 100000; i++)
{
var s = Regex.Replace(str, #"\D", "");
}
sw.Stop();
Console.WriteLine(sw.ElapsedMilliseconds); //Takes up to 600 ms
sw.Reset();
sw.Start();
for (int i = 0; i < 100000; i++)
{
var newstr = String.Join("", str.Where(c => Char.IsDigit(c)));
}
sw.Stop();
Console.WriteLine(sw.ElapsedMilliseconds); //Takes up to 109 ms
So regular expression implementation works predictably slow. Join and new string gives pretty similar results, also it might very depending from use case. Did not test implementation with manual string looping, I believe, it might give best results.
Update.
Also there is RegexOptions.Compiled option for regular expression, usage from example was intended. But for clarity of test, can say, that compiled regular expression gives in example above nearly 150 ms performance boost, which is still pretty slow (4 times slower then other).
CODE:
using System;
using System.Linq;
using System.Text.RegularExpressions;
using System.Diagnostics;
public class Foo
{
public static void Main()
{
string s = string.Empty;
TimeSpan e;
var sw = new Stopwatch();
//REGEX
sw.Start();
for(var i = 0; i < 10000; i++)
{
s = "123213!¤%//)54!!#¤!#%13425";
s = Regex.Replace(s, #"\D", "");
}
sw.Stop();
e = sw.Elapsed;
Console.WriteLine(s);
Console.WriteLine(e);
sw.Reset();
//NONE REGEX
sw.Start();
for(var i = 0; i < 10000; i++)
{
s = "123213!¤%//)54!!#¤!#%13425";
s = new string(s.Where(c => char.IsDigit(c)).ToArray());
}
sw.Stop();
e = sw.Elapsed;
Console.WriteLine(s);
Console.WriteLine(e);
}
}
OUTPUT:
1232135413425
00:00:00.0564964
1232135413425
00:00:00.0107598
Conclusion: This clearly favors the none regex method to solve this issue.
What have you tried?
static Regex rxNonDigits = new Regex( #"[^\d]+");
public static string StripNonDigits( string s )
{
return rxNonDigits.Replace(s,"") ;
}
Or the probably more efficient
public static string StripNonDigits( string s )
{
StringBuilder sb = new StrigBuilder(s.Length) ;
foreach ( char c in s )
{
if ( !char.IsDigit(c) ) continue ;
sb.Append(c) ;
}
return sb.ToString() ;
}
Or the equivalent one-liner:
public static string StripNonDigits( string s )
{
return new StringBuilder(s.Length)
.Append( s.Where(char.IsDigit).ToArray() )
.ToString()
;
}
Or if you don't care about other culture's digits and only care about ASCII decimal digits, you could save a [perhaps] expensive lookup and do two compares:
public static string StripNonDigits( string s )
{
return new StringBuilder(s.Length)
.Append( s.Where( c => c >= '0' && c <= '9' ).ToArray() )
.ToString()
;
}
It should be noted that the LINQ solutions almost certainly require constructing an intermediate array (something that's not required using a StringBuilder. You could also use LINQ aggregation:
s.Where( char.IsDigit ).Aggregate(new StringBuilder(s.Length), (sb,c) => sb.Append(c) ).ToString()
There More Than One Way To Do It!
The ^ excludes an expression from your match. Use it with \d, which matches digits 0-9, and replace this with nothing.
var cleanString = Regex.Replace("123abc,.é", "^\d", "");
You could simply do the following, The caret (^) inside of a character class [ ] is the negation operator.
var pattern = #"[^0-9]+";
var replaced = Regex.Replace("5435%$% r3443_+_+**╥╡←", pattern, "");
Output:
54353443

Why is StringBuilder slower than string concatenation?

Why is StringBuilder slower when compared to + concatenation?
StringBuilder was meant to avoid extra object creation, but why does it penalize performance?
static void Main(string[] args)
{
int max = 1000000;
for (int times = 0; times < 5; times++)
{
Console.WriteLine("\ntime: {0}", (times+1).ToString());
Stopwatch sw = Stopwatch.StartNew();
for (int i = 0; i < max; i++)
{
string msg = "Your total is ";
msg += "$500 ";
msg += DateTime.Now;
}
sw.Stop();
Console.WriteLine("String +\t: {0}ms", ((int)sw.ElapsedMilliseconds).ToString().PadLeft(6));
sw = Stopwatch.StartNew();
for (int j = 0; j < max; j++)
{
StringBuilder msg = new StringBuilder();
msg.Append("Your total is ");
msg.Append("$500 ");
msg.Append(DateTime.Now);
}
sw.Stop();
Console.WriteLine("StringBuilder\t: {0}ms", ((int)sw.ElapsedMilliseconds).ToString().PadLeft(6));
}
Console.Read();
}
EDIT: Moving out of scope variables as suggested:
Change so that the StringBuilder isn't instantiated all the time, instead .Clear() it:
time: 1
String + : 3348ms
StringBuilder : 3151ms
time: 2
String + : 3346ms
StringBuilder : 3050ms
etc.
Note that this still tests exactly the same functionality, but tries to reuse resources a bit smarter.
Code: (also live on http://ideone.com/YuaqY)
using System;
using System.Text;
using System.Diagnostics;
public class Program
{
static void Main(string[] args)
{
int max = 1000000;
for (int times = 0; times < 5; times++)
{
{
Console.WriteLine("\ntime: {0}", (times+1).ToString());
Stopwatch sw = Stopwatch.StartNew();
for (int i = 0; i < max; i++)
{
string msg = "Your total is ";
msg += "$500 ";
msg += DateTime.Now;
}
sw.Stop();
Console.WriteLine("String +\t: {0}ms", ((int)sw.ElapsedMilliseconds).ToString().PadLeft(6));
}
{
Stopwatch sw = Stopwatch.StartNew();
StringBuilder msg = new StringBuilder();
for (int j = 0; j < max; j++)
{
msg.Clear();
msg.Append("Your total is ");
msg.Append("$500 ");
msg.Append(DateTime.Now);
}
sw.Stop();
Console.WriteLine("StringBuilder\t: {0}ms", ((int)sw.ElapsedMilliseconds).ToString().PadLeft(6));
}
}
Console.Read();
}
}
You are creating a new instance of StringBuilder with every iteration, and that incurs some overhead. Since you are not using it for what it's actually meant to do (ie: build large strings which would otherwise require many string concatenation operations), it's not surprising to see worse performance than concatenation.
A more common comparison / usage of StringBuilder is something like:
string msg = "";
for (int i = 0; i < max; i++)
{
msg += "Your total is ";
msg += "$500 ";
msg += DateTime.Now;
}
StringBuilder msg_sb = new StringBuilder();
for (int j = 0; j < max; j++)
{
msg_sb.Append("Your total is ");
msg_sb.Append("$500 ");
msg_sb.Append(DateTime.Now);
}
With this, you'll observe a significant performance difference between StringBuilder and concatenation. And by "significant" I mean orders of magnitude, not the ~ 10% difference you are observing in your examples.
Since StringBuilder doesn't have to build tons of intermediary strings that will just get thrown away, you get much better performance. That's what it's meant for. For smaller strings, you are better off using string concatenation for simplicity and clarity.
The benefits of StringBuilder should be noticeable with longer strings.
Every time you concatenate a string you create a new string object, so the longer the string, the more is needed to copy from the old string to the new string.
Also, creating many temporary objects may have an adverse effect on performance that is not measurable by a StopWatch, because it "pollutes" the managed heap with temporary objects and may cause more garbage collection cycles.
Modify your test to create (much) longer strings and use (many) more concatenations / append operations and the StringBuilder should perform better.
Note that
string msg = "Your total is ";
msg += "$500 ";
msg += DateTime.Now;
compiles down to
string msg = String.Concat("Your total is ", "$500 ");
msg = String.Concat(msg, DateTime.Now.ToString());
This totals two concats and one ToString per iteration. Also, a single String.Concat is really fast, because it knows how large the resulting string will be, so it only allocates the resulting string once, and then quickly copies the source strings into it. This means that in practice
String.Concat(x, y);
will always outperform
StringBuilder builder = new StringBuilder();
builder.Append(x);
builder.Append(y);
because StringBuilder cannot take such shortcuts (you could call a thirs Append, or a Remove, that's not possible with String.Concat).
The way a StringBuilder works is by allocating an initial buffer and set the string length to 0. With each Append, it has to check the buffer, possibly allocate more buffer space (usually copying the old buffer to the new buffer), copy the string and increment the string length of the builder. String.Concat does not need to do all this extra work.
So for simple string concatenations, x + y (i.e., String.Concat) will always outperform StringBuilder.
Now, you'll start to get benefits from StringBuilder once you start concatenating lots of strings into a single buffer, or you're doing lots of manipulations on the buffer, where you'd need to keep creating new strings when not using a StringBuilder. This is because StringBuilder only occasionally allocates new memory, in chunks, but String.Concat, String.SubString, etc. (nearly) always allocate new memory. (Something like "".SubString(0,0) or String.Concat("", "") won't allocate memory, but those are degenerate cases.)
In addition to not using StringBuilder as in the most efficient manner, you're also not using string concatenation as efficiently as possible. If you know how many strings you're concatenating ahead of time, then doing it all on one line should be fastest. The compiler optimizes the operation so that no intermediate strings are generated.
I added a couple more test cases. One is basically the same as what sehe suggested, and the other generates the string in one line:
sw = Stopwatch.StartNew();
builder = new StringBuilder();
for (int j = 0; j < max; j++)
{
builder.Clear();
builder.Append("Your total is ");
builder.Append("$500 ");
builder.Append(DateTime.Now);
}
sw.Stop();
Console.WriteLine("StringBuilder (clearing)\t: {0}ms", ((int)sw.ElapsedMilliseconds).ToString().PadLeft(6));
sw = Stopwatch.StartNew();
for (int i = 0; i < max; i++)
{
msg = "Your total is " + "$500" + DateTime.Now;
}
sw.Stop();
Console.WriteLine("String + (one line)\t: {0}ms", ((int)sw.ElapsedMilliseconds).ToString().PadLeft(6));
And here is an example of the output I see on my machine:
time: 1
String + : 3707ms
StringBuilder : 3910ms
StringBuilder (clearing) : 3683ms
String + (one line) : 3645ms
time: 2
String + : 3703ms
StringBuilder : 3926ms
StringBuilder (clearing) : 3666ms
String + (one line) : 3625ms
In general:
- StringBuilder does better if you're building a large string in a lot of steps, or you don't know how many strings will be concatenated together.
- Mashing them all together in a single expression is better whenever it's a reasonable option option.
I think its better to compare effeciancy between String and StringBuilder rather then time.
what msdn says:
A String is called immutable because its value cannot be modified once it has been created. Methods that appear to modify a String actually return a new String containing the modification. If it is necessary to modify the actual contents of a string-like object, use the System.Text.StringBuilder class.
string msg = "Your total is "; // a new string object
msg += "$500 "; // a new string object
msg += DateTime.Now; // a new string object
see which one is better.
Here is an example that demonstrates a situation in which StringBuilder will execute more quickly than string concatenation:
static void Main(string[] args)
{
const int sLen = 30, Loops = 10000;
DateTime sTime, eTime;
int i;
string sSource = new String('X', sLen);
string sDest = "";
//
// Time StringBuilder.
//
for (int times = 0; times < 5; times++)
{
sTime = DateTime.Now;
System.Text.StringBuilder sb = new System.Text.StringBuilder((int)(sLen * Loops * 1.1));
Console.WriteLine("Result # " + (times + 1).ToString());
for (i = 0; i < Loops; i++)
{
sb.Append(sSource);
}
sDest = sb.ToString();
eTime = DateTime.Now;
Console.WriteLine("String Builder took :" + (eTime - sTime).TotalSeconds + " seconds.");
//
// Time string concatenation.
//
sTime = DateTime.Now;
for (i = 0; i < Loops; i++)
{
sDest += sSource;
//Console.WriteLine(i);
}
eTime = DateTime.Now;
Console.WriteLine("Concatenation took : " + (eTime - sTime).TotalSeconds + " seconds.");
Console.WriteLine("\n");
}
//
// Make the console window stay open
// so that you can see the results when running from the IDE.
//
}
Result # 1
String Builder took :0 seconds.
Concatenation took : 8.7659616 seconds.
Result # 2
String Builder took :0 seconds.
Concatenation took : 8.7659616 seconds.
Result # 3
String Builder took :0 seconds.
Concatenation took : 8.9378432 seconds.
Result # 4
String Builder took :0 seconds.
Concatenation took : 8.7972128 seconds.
Result # 5
String Builder took :0 seconds.
Concatenation took : 8.8753408 seconds.
StringBulder is much faster than + concatenation..

Writing a string to a file causes an exception in C#

I'm getting a "FormatException: Input string was not in a correct format" error that I don't understand.
I'm using the following lines to write a string to a text file:
using (StreamWriter sw = new StreamWriter(myfilename, false, System.Text.Encoding.GetEncoding(enc)))
{
sw.Write(mystring, Environment.NewLine);
}
(the encoding part is because I do have an option in my application to set it to utf-8 or iso-8859-1... but I think that's irrelevant).
All of my strings write out just fine except this one string that is different from the others because it actually has a snippet of javascript code in it. I'm sure that one of the special characters there might be causing the problem but how do I know?
The one thing I tried was to insert the following line just before the sw.Write statement above:
System.Console.WriteLine(mystring);
and it wrote out to the console just fine - no error.
Help?
Thanks! (and Happy New Year!)
-Adeena
The overload you are using takes the format as the first parameter, and objects to inject after that.
You can do either of the following:
sw.Write(mystring + Environment.NewLine);
or
sw.Write("{0}{1}", mystring, Environment.NewLine);
In response to the comments from DK, I tested to what extend string concatenation is slower. I made this setup with three options;
concatenating the string
calling sw.Write twice
calling sw.WriteLine
On my machine, the second option is about 88% faster than average. At 10000000 iterations they use 3517, 2420 and 3385 milliseconds.
It should only be significant if this is code that is called many times in your program.
using System;
using System.IO;
using System.Text;
class Program
{
static void Main(string[] args)
{
const string myString = "kdhlkhldhcøehdhkjehdkhekdhk";
int iterations=getIntFromParams(args, 0, 10);
int method = getIntFromParams(args, 1, 0);
var fileName=Path.GetTempFileName();
using (StreamWriter sw = new StreamWriter(fileName, false, Encoding.Default))
{
switch (method)
{
case 0:
Console.WriteLine("Starting method with concatenation. Iterations: " + iterations);
var start0 = DateTimeOffset.Now;
for (int i = 0; i < iterations; i++)
{
sw.Write(myString + Environment.NewLine);
}
var time0 = DateTimeOffset.Now - start0;
Console.WriteLine("End at " + time0.TotalMilliseconds + " ms.");
break;
case 1:
Console.WriteLine("Starting method without concatenation. Iterations: " + iterations);
var start1 = DateTimeOffset.Now;
for (int i = 0; i < iterations; i++)
{
sw.Write(myString);
sw.Write(Environment.NewLine);
}
var time1 = DateTimeOffset.Now - start1;
Console.WriteLine("End at " + time1.TotalMilliseconds + " ms.");
break;
case 2:
Console.WriteLine("Starting method without concatenation, using WriteLine. Iterations: " + iterations);
var start2 = DateTimeOffset.Now;
for (int i = 0; i < iterations; i++)
{
sw.WriteLine(myString);
}
var time2 = DateTimeOffset.Now - start2;
Console.WriteLine("End at " + time2.TotalMilliseconds + " ms.");
break;
}
}
}
private static int getIntFromParams(string[] args, int index, int #default)
{
int value;
try
{
if (!int.TryParse(args[index], out value))
{
value = #default;
}
}
catch(IndexOutOfRangeException)
{
value = #default;
}
return value;
}
}

Categories