I clicked together a small WinForms app for testing. It has two multiline textboxes and a single button, which on press sends a request to a server and posts response headers and content into the textboxes like this:
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
int len = 0;
foreach (var header in response.Headers)
{
var str = header.ToString();
textBox1.AppendText(str + "=" + response.Headers[str] + "\n");
if (str == "Content-Length") len = Convert.ToInt32(response.Headers[str]);
}
Stream respStream = response.GetResponseStream();
byte[] x = new byte[len];
respStream.Read(x, 0, len);
var s = new string(ascii.GetChars(x, 0, len));
// textBox2.Text = s;
textBox2.Clear();
textBox2.AppendText(s);
MessageBox.Show(textBox2.TextLength.ToString(), s.Length.ToString());
But no matter whether I use AppendText or whether I assign the string, the MessageBox always shows the caption 7653 with message 3964, and the headers textbox contains the line Content-length=7653.
So it seems that the string is not completely appended to the TextBox. Why would that be?
Btw: I am requesting an HTML document; the last two chars shown are ".5", and the first two chars missing are "16", so it does not break at some special characters.
Check out this Post
Your problem is that with Stream.Read you may read less than the total number of characters as they may not be available yet on the network.
So your string already contains only the first part of the text. s.Length indicates the right number of characters as it gets copied over from the byte array x but most of the characters are 0 (Char '\0'). textBox2.TextLength then indicates the right number of characters that have been read. I suppose it trims the '\0' characters.
You should use a while loop instead and check the result of Read as indicated before.
Also check the encoding of your html page. For UTF8 (default in HTML 5) one byte doesn't necessarily correspond to one character.
Related
I have some xml files where some control sequences are included in the text: EOT,ETX(anotherchar)
The other char following EOT comma ETX is not always present and not always the same.
Actual example:
<FatturaElettronicaHeader xmlns="">
</F<EOT>‚<ETX>èatturaElettronicaHeader>
Where <EOT> is the 04 char and <ETX> is 03. As I have to parse the xml this is actually a big issue.
Is this some kind of encoding I never heard about?
I have tried to remove all the control characters from my string but it will leave the comma that is still unwanted.
If I use Encoding.ASCII.GetString(file); the unwanted characters will be replaced with a '?' that is easy to remove but it will still leave some unwanted characters causing parse issues:
<BIC></WBIC> something like this.
string xml = Encoding.ASCII.GetString(file);
xml = new string(xml.Where(cc => !char.IsControl(cc)).ToArray());
I hence need to remove all this kind of control character sequences to be able to parse this kind of files and I'm unsure about how to programmatically check if a character is part of a control sequence or not.
I have find out that there are 2 wrong patterns in my files: the first is the one in the title and the second is EOT<.
In order to make it work I looked at this thread: Remove substring that starts with SOT and ends EOT, from string
and modified the code a little
private static string RemoveInvalidCharacters(string input)
{
while (true)
{
var start = input.IndexOf('\u0004');
if (start == -1) break;
if (input[start + 1] == '<')
{
input = input.Remove(start, 2);
continue;
}
if (input[start + 2] == '\u0003')
{
input = input.Remove(start, 4);
}
}
return input;
}
A further cleanup with this code:
static string StripExtended(string arg)
{
StringBuilder buffer = new StringBuilder(arg.Length); //Max length
foreach (char ch in arg)
{
UInt16 num = Convert.ToUInt16(ch);//In .NET, chars are UTF-16
//The basic characters have the same code points as ASCII, and the extended characters are bigger
if ((num >= 32u) && (num <= 126u)) buffer.Append(ch);
}
return buffer.ToString();
}
And now everything looks fine to parse.
sorry for the delay in responding,
but in my opinion the root of the problem might be an incorrect decoding of a p7m file.
I think originally the xml file you are trying to sanitize was a .xml.p7m file.
I believe the correct way to sanitize the file is by using a library such as Buoncycastle in java or dotnet and the class CmsSignedData.
CmsSignedData cmsObj = new CmsSignedData(content);
if (cmsObj.SignedContent != null)
{
using (var stream = new MemoryStream())
{
cmsObj.SignedContent.Write(stream);
content = stream.ToArray();
}
}
I just ran into a problem I haven't seen before. The problem short is that I need to send two different strings to a method which will validate if the string are the same.
one of the string look like this
Sample 1
JVBERi0xLjQNCiW1tbW1DQoxIDAgb2JqDQo8PC9UeXBlL0NhdGFsb2cvUGFnZXMgMiAwIFIvTGFu
ZyhkYS1ESykgL1N0cnVjdFRyZWVSb290IDU3IDAgUi9NYXJrSW5mbzw8L01hcmtlZCB0cnVlPj4v
the second one looks like
Sample 2 ZyhkYS1ESykgL1N0cnVjdFRyZWVSb290IDU3IDAgUi9NYXJrSW5mbzw8L01hcmtlZCB0cnVlPj4vZyhkYS1ESykgL1N0cnVjdFRyZWVSb290IDU3IDAgUi9NYXJrSW5mbzw8L01hcmtlZCB0cnVlPj4v
The actually string is a PDF document compressed into base64 (this is only a part of it)
I tried to take sample one into notepad++ and say show all special characters, it shows me CRLF in the end of each line.
Now im in the situation that i need to have sample 2 looking like sample 1, so I need to read a file into the same encoding, is this possible?
So to sum up here is what I want to do
EDIT/ADD:
What i want is that
1. Take a pdf
2. Convert it into base64encoded with cr/lf
3. in a validation method in another library it needs to be validated as this format.
Well I didnt find any nice way to create a CR/LF split
byte[] bytes = System.IO.File.ReadAllBytes(#"C:\Testdata\SSVALID.pdf");
string temp_inBase64 = Convert.ToBase64String(bytes);
string returnString = "";
int maxLenght = 76;
int counts = temp_inBase64.Length / maxLenght;
for (int i = 0; i < counts; i++)
{
returnString += temp_inBase64.Substring((i * 76), 76);
returnString += "\r\n";
}
returnString += temp_inBase64.Substring(76 * counts, temp_inBase64.Length - (76 * counts));
My client requirment has fixed length file records in the format of header, body and footer but in the footer they wants to have an empty space of 1966 lenght . I tried this using difffent butttons for header and footer and body but was unable to specify space at the end. this was my code .. space is not working in this while creating footer.
FileStream fs = new FileStream(#"C:\Users\IT-Administrator\Desktop\ee.txt", FileMode.Open, FileAccess.ReadWrite);
fs.Seek(0, SeekOrigin.End);
StreamWriter sw = new StreamWriter(fs);
sw.WriteLine(comboBox6.Text + textBox2.Text + textBox3.Text + textBox4.Text + **SPACE(1966)** );
sw.Close();
fs.Close();**strong text**
Use String.PadRight() to pad the string.
Say for example the max string length was 2000 characters, you can do something like this:
string example = "Example";
string full_example = example.PadRight(2000);
This will take the length of the original string and pad it out with spaces until it reaches the desired width.
In your case if you wanted exactly 1966 spaces though you can do this:
string spaces = String.Empty.PadRight(1966);
You can do this by using the overload of WriteLine that accepts a format specifier.
If you want the last element to take a total of 1966 characters, you can write :
using(var sw=new StreamWriter(#"C:\Users\IT-Administrator\Desktop\ee.txt"))
{
sw.WriteLine("{0}{1}{2}{3,-1966}",comboBox6.Text ,textBox2.Text,
textBox3.Text,textBox4.Text );
}
This way it's much easier to see what the actual string will look like. For example, you can see that you are actually joining all elements in one continuous string. Perhaps, what you wanted to do was to separate them by spaces, eg: "{0} {1} {3} {4,-1966}"
If you want the the last element to be followed by 1966 spaces:
using(var sw=new StreamWriter(#"C:\Users\IT-Administrator\Desktop\ee.txt"))
{
sw.WriteLine("{0}{1}{3}{4}{5,-1966}",comboBox6.Text ,textBox2.Text,
textBox3.Text,textBox4.Text,' ');
}
In the above code, using makes sure the StreamWriter will close even if an exception occurs. The code also avoids creating both a StreamWriter and FileStream by creating the StreamWriter with a path argument
If you want to create a string consisting of 1966 spaces, you can use the string constructor that takes a character and a number of times to repeat it: new String(' ', 1966).
If you want to pad strings out to a particular length, you can use PadRight or PadLeft as appropriate.
I'm running three counters, one to return the total amount of chars, one to return the number of '|' chars in my .txt file (total). And one to read how many separate lines are in my text file. I'm assuming my counters are wrong, I'm not sure. In my text file there are some extra '|' chars, but that is a bug I need to fix later...
The Message Boxes show
"Lines = 8"
"Entries = 8"
"Total Chars = 0"
Not sure if it helps but the .txt file is compiled using a streamwriter, and I have a datagridview saved to a string to create the output. Everything seems okay with those functions.
Here is a copy of the text file I'm reading
Matthew|Walker|MXW320|114282353|True|True|True
Audrey|Walker|AXW420|114282354|True|True|True
John|Doe|JXD020|111222333|True|True|False
||||||
And here is the code.
private void btnLoadList_Click(object sender, EventArgs e)
{
var loadDialog = new OpenFileDialog
{
InitialDirectory = Convert.ToString(Environment.SpecialFolder.MyDocuments),
Filter = "Text (*.txt)|*.txt",
FilterIndex = 1
};
if (loadDialog.ShowDialog() != DialogResult.OK) return;
using (new StreamReader(loadDialog.FileName))
{
var lines = File.ReadAllLines(loadDialog.FileName);//Array of all the lines in the text file
foreach (var assocStringer in lines)//For each assocStringer in lines (Runs 1 cycle for each line in the text file loaded)
{
var entries = assocStringer.Split('|'); // split the line into pieces (e.g. an array of "Matthew", "Walker", etc.)
var obj = (Associate) _bindingSource.AddNew();
if (obj == null) continue;
obj.FirstName = entries[0];
obj.LastName = entries[1];
obj.AssocId = entries[2];
obj.AssocRfid = entries[3];
obj.CanDoDiverts = entries[4];
obj.CanDoMhe = entries[5];
obj.CanDoLoading = entries[6];
}
}
}
Hope you guys find the bug(s) here. Sorry if the formatting is sloppy I'm self-taught, no classes. Any extra advice is welcomed, be as honest and harsh as need be, no feelings will be hurt.
In summary
Why is this program not reading the correct values from the text file I'm using?
Not totally sure I get exactly what you're trying to do, so correct me if I'm off, but if you're just trying to get the line count, pipe (|) count and character count for the file the following should get you that.
var lines = File.ReadAllLines(load_dialog.FileName);
int lineCount = lines.Count();
int totalChars = 0;
int totalPipes = 0; // number of "|" chars
foreach (var s in lines)
{
var entries = s.Split('|'); // split the line into pieces (e.g. an array of "Matthew", "Walker", etc.)
totalChars += s.Length; // add the number of chars on this line to the total
totalPipes = totalPipes + entries.Count() - 1; // there is always one more entry than pipes
}
All the Split() is doing is breaking the full line into an array of the individual fields in the string. Since you only seem to care about the number of pipes and not the fields, I'm not doing much with it other than determining the number of pipes by taking the number of fields and subtracting one (since you don't have a trailing pipe on each line).
Hi can anyone explain these lines of codes, I need to understand how it works in order to proceed with what I am doing
if (e.Error == null){
Stream responseStream = e.Result;
StreamReader responseReader = new StreamReader(responseStream);
string response = responseReader.ReadToEnd();
string[] split1 = Regex.Split(response, "},{");
List<string> pri1 = new List<string>(split1);
pri1.RemoveAt(0);
string last = pri1[pri1.Count() - 1];
pri1.Remove(last);
}
// Check if there was no error
if (e.Error == null)
{
// Streams are a way to read/write information from/to somewhere
// without having to manage buffer allocation and such
Stream responseStream = e.Result;
// StreamReader is a class making it easier to read from a stream
StreamReader responseReader = new StreamReader(responseStream);
// read everything that was written to a stream and convert it to a string using
// the character encoding that was specified for the stream/reader.
string response = responseReader.ReadToEnd();
// create an array of the string by using "},{" as delimiter
// string.Split would be more efficient and more straightforward.
string[] split1 = Regex.Split(response, "},{");
// create a list of the array. Lists makes it easier to work with arrays
// since you do not have to move elements manually or take care of allocations
List<string> pri1 = new List<string>(split1);
pri1.RemoveAt(0);
// get the last item in the array. It would be more efficient to use .Length instead
// of Count()
string last = pri1[pri1.Count() - 1];
// remove the last item
pri1.Remove(last);
}
I would use a LinkedList instead of List if the only thing to do was to remove the first and last elements.
It's reading the response stream as a string, making the assumption that the string consists of sequences "{...}" separated by commas, e.g.:
{X},{Y},{Z}
then splits the string on "},{", giving an array of
{X
Y
Z}
then removes the first brace from the first element of the array ( {X => X ) and the end brace from the last element of the array ( Z} => Z).
From what I can see, it is reading from a stream that could have came from TCP.
It reads the whole chunk of data, then separate the chunk using the delimiter },{.
So if you have something like abc},{dec , it will be placed into split1 array with 2 values, split1 [0]=abc , split1 [1]=dec.
After that, it basically remove the 1st and the last content
It is processing an error output.
It received a stream from the e (I guess it is an exception), reads it.
It looks something like :
""{DDD},{I failed},{Because},{There was no signal}{ENDCODE}
It splits it into different string, and removes to fist and last entries (DDD, ENDCODE)