write xml file c# asp.net, and control file size - c#
I create an xml file and write some information in it.
When i do this operation, i follow these steps:
I get data from db and map it my object list;
In the foreach iteration statement write the xml file.
But my data size changable.
My problem is my xml file size must not exceed 200 mb. If my data exceeds 200 mb. I have to divide into two parts, if exceeds 400 mb divide into three parts.
Can I control the data size before filling the xml file?
For example if my list object data size exceeds 200 mb, I will divide my list object into two parts.
I don't understand you write xml method, but you can try something like this.
Main idea is count length of each record in list
[Serializable]
public class MyData
{
public int id { get; set; }
public string data { get; set; }
}
static void Main(string[] args)
{
string fileName = string.Format("xmlFile_{0}.xml", DateTime.Now.ToString("dd.mm.ss"));
int dataLength = 0;
int limit = 100500;
List<MyData> list = new List<MyData>();
for (int i = 0; i <= 1000; i++)
{
Random r = new Random();
string preparedData = Convert.ToBase64String(
System.Text.Encoding.UTF8.GetBytes(r.Next(int.MaxValue).ToString())
);
MyData mydata = new MyData { id = i, data = preparedData };
StringWriter stringWriter = new StringWriter();
XmlDocument xmlDoc = new XmlDocument();
XmlTextWriter xmlWriter = new XmlTextWriter(stringWriter);
XmlSerializer serializer = new XmlSerializer(typeof(MyData));
serializer.Serialize(xmlWriter, mydata);
string xmlResult = stringWriter.ToString();
dataLength += xmlResult.Length;
if (dataLength <= limit)
// insert you write method here
File.AppendAllText(fileName, xmlResult);
else
{
// create new file or something else you want
}
list.Add(mydata);
}
Console.WriteLine("Finished");
Console.ReadLine();
}
Related
Writing to same csv line twice?
I am attempting to create code that will write values into a csv file, do some other unrelated code and then later on add an extra value to that line static void Main(string[] args) { int newNumber = 110; var records = new List<MovieInfo> { new MovieInfo {Rating = newNumber, Price = 44}, }; var config = new CsvConfiguration(CultureInfo.InvariantCulture) { HasHeaderRecord = false, }; string filePath = #"C:\file\path\go\brrrr"; using (var stream = File.Open(filePath, FileMode.Append)) using (var writer = new StreamWriter(stream)) using (var csv = new CsvWriter(writer, config)) { csv.WriteRecords(records); } //-------------------------------------- //other unrelated code things happen here //-------------------------------------- double value = 4; string thirdValue = "," + value; File.AppendAllText(filePath, thirdValue); } public class MovieInfo { public int Rating { get; set; } public int Price { get; set; } } The output of this code is this Output code Is it possible to adjust the code so that the output will be 110,44,4 instead? Additional info if it is relevant would be that the line in question will always be the last in the file. Any help is appreciated
When you call csv.WriteRecords(records); all records are written to the output file and each record is separated by a newline, even the last record has a new line appended. Instead of writing every record in one go, you could write a record at time with the WriteRecord method. This method doesn't write the newline. A new line is added when you call the NextRecord method. So looping on your records minus one you can control the output of the newline on the last line: void Main() { int newNumber = 110; var records = new List<MovieInfo> { new MovieInfo {Rating = 200, Price = 30}, new MovieInfo {Rating = newNumber, Price = 44}, }; var config = new CsvConfiguration(CultureInfo.InvariantCulture) { HasHeaderRecord = false, }; string filePath = #"E:\temp\movieinfo.csv"; using (var stream = File.Open(filePath, FileMode.Append)) using (var writer = new StreamWriter(stream)) using (var csv = new CsvWriter(writer, config)) { // Write all records minus one. for (int x = 0; x < records.Count - 1; x++) { csv.WriteRecord(records[x]); csv.NextRecord(); } // Write the last record without the newline csv.WriteRecord(records[records.Count-1]); } //-------------------------------------- //other unrelated code things happen here //-------------------------------------- double value = 4; string thirdValue = "," + value; File.AppendAllText(filePath, thirdValue); }
Using data from InnerText
Is there any option of using data - extracted from InnerText - as the pixels 'y' coordinates position? I managed to get string elements from .xml file - tag "SequenceInfo". Example of .xml file: <SequenceInfo HasSmoke="" Azimuth="267.2" Inclination="682" Zoom="10329" TowerName="Makoszka" Time="2015-03-18 13:10:22"> <Horizon>316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,320,320,320,321,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,324,324,324,324,324,324,324,326,326,326,326,326,326,326,326,324,324,322,322,322,322,322,322,322,322,322,322,322,322,323,324,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,324,324,322,322,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320</Horizon> </SequenceInfo> I get the text content of the specified node as follows: 316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,320,320,320,321,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,324,324,324,324,324,324,324,326,326,326,326,326,326,326,326,324,324,322,322,322,322,322,322,322,322,322,322,322,322,323,324,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,324,324,322,322,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320 Such data are being stored in object 'xtr' (InnerText property). Can we push this data even further? For example as 'y' coordinates? Part of my code below: XmlDocument xtr = new XmlDocument(); string fileName = OFD.FileName; FileInfo fileInfo = new FileInfo(fileName); string directoryFullPath = fileInfo.DirectoryName; fileName = Path.Combine(directoryFullPath, "info.xml"); xtr.Load(fileName); XmlNodeList list = xtr.GetElementsByTagName("SequenceInfo");
It's unclear if you've actually retrieved the data, and what you want to do with it once you've extracted it...but here's an example that should get you started: // ... get the data from your XML somehow ... string data = "316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,316,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,320,320,320,321,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,322,324,324,324,324,324,324,324,326,326,326,326,326,326,326,326,324,324,322,322,322,322,322,322,322,322,322,322,322,322,323,324,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,326,324,324,322,322,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320"; // Convert the Text Data to Points: var points = from y in data.Split(",".ToCharArray()) select new Point(0, int.Parse(y)); // Do something with the Points: foreach(Point p in points) { Console.WriteLine(p.ToString()); }
Problem solved. Here's my code: XmlDocument xtr = new XmlDocument(); string fileName = OFD.FileName; FileInfo fileInfo = new FileInfo(fileName); string directoryFullPath = fileInfo.DirectoryName; fileName = Path.Combine(directoryFullPath, "info.xml"); xtr.Load(fileName); XmlNodeList list = xtr.GetElementsByTagName("SequenceInfo"); string[] punkty = xtr.InnerText.Split(','); List<Point> punkty1 = new List<Point>(); for (int i = 0; i < punkty.Length; i++) { punkty1.Add(new Point { X = i, Y = int.Parse(punkty[i])}); }
CSV file creation is shorter than expected
I'm creating a CSV file, I'm using C# and CsvHelper to do so. My CSV file ends up being 205 lines long each time. I know for certain that it should be creating 240 entries, which is what I want. It seems to stop creating the CSV file at 205 lines. When running it several times it will produce the same result of 205 entry's. Interestingly the last field it attempts to write is one letter short and I'm not sure why. Below is the full code. using System; using System.Collections.Generic; using Newtonsoft.Json; using CsvHelper; using System.IO; namespace PinGenerator { class Program { static void Main(string[] args) { GeneratePins generatePins = new GeneratePins(); generatePins.Start(); Console.ReadLine(); } } public class GeneratePins { private Dictionary<string, String> pinNumbers = new Dictionary<string, String>(); private List<String> duplicatePinCheck = new List<string>(); private Random random = new Random(); // Runs the sequence for the generation of TimeSpans & Pin Numbers. // Stores these into JSON / CSV Files public void Start() { TimeSpan timeSpan = new TimeSpan(); TimeSpan maxTime = TimeSpan.FromHours(2); TimeSpan currentTimeSpan = TimeSpan.FromSeconds(30); string currentPin = "0000"; // CSV File Creation TextWriter textWriter = File.CreateText(#"pinNumber.csv"); var csv = new CsvWriter(textWriter); while (timeSpan.Duration() < maxTime.Duration()) { // Create TimeSpan & Pin timeSpan = timeSpan.Add(currentTimeSpan); currentPin = RandomNumber(); // Duplicate Check while (duplicatePinCheck.Contains(currentPin)) { currentPin = RandomNumber(); } duplicatePinCheck.Add(currentPin); // Cache Results string entryPinNumber = currentPin; string entryTimeSpan = timeSpan.ToString(); // JSON pinNumbers.Add(entryTimeSpan, currentPin); // CSV Creation - Write to CSV File csv.WriteField(entryTimeSpan); csv.WriteField(entryPinNumber); csv.NextRecord(); // CONSOLE Console.WriteLine(entryPinNumber + " / " + timeSpan.ToString()); } string json = JsonConvert.SerializeObject(pinNumbers, Formatting.Indented); // Write to JSON File using (System.IO.StreamWriter file = File.CreateText(#"pinNumbers.json")) { JsonSerializer serializer = new JsonSerializer(); serializer.Serialize(file, pinNumbers); } Console.WriteLine("Created " + pinNumbers.Count() + " pin numbers."); } public string RandomNumber() { String result = random.Next(0, 9999).ToString(); result = result.PadLeft(4, '0'); return result; } } }
TextWriter textWriter = File.CreateText(#"pinNumber.csv"); Needed to be changed to StreamWriter streamWriter = File.CreateText(#"pinNumber.csv");
C# Pass multiple parameters into XML using Queue
I have a webservice that obtains data from Oracle CRM OnDemand. I want to create another WS that takes the fields for a given customer record and passes those fields as parameters into an XML writer which then creates the XML to be passed to another webservice (being developed by another team). I can create the XML fine and pass the parameters. However, I am only testing 3-4 fields and passing them. I will need way more than 4 parameters to be passed, and I know this is pretty poor programming to create a function that takes 3+ parameters. (EDIT) I have created a queue that takes in the parameters from the page, and I pass just the queue. I want to dequeue the data field followed by a string of what I want to pass into the XML page. This is what I have right now. ...for (int intIndx = 0; intIndx < intCount; intIndx++) { //Create queue to store all the data obtained from a given Account Queue<string> q = new Queue<string>(); //Easier to reference var acctName= objAcctQryOut.ListOfAccount[intIndx].AccountName; var acctWebsite = objAcctQryOut.ListOfAccount[intIndx].WebSite; q.Enqueue(acctName); addyInsert.CountryCode = objAcctQryOut.ListOfAccount[intIndx].PrimaryBillToCountry; q.Enqueue(addyInsert.CountryCode); addyInsert.Line1 = objAcctQryOut.ListOfAccount[intIndx].PrimaryBillToStreetAddress; q.Enqueue(addyInsert.Line1); addyInsert.Line2 = accountInfo.PrimaryBillToStreetAddress2; q.Enqueue(addyInsert.Line2); addyInsert.Line3 = accountInfo.PrimaryBillToStreetAddress3; q.Enqueue(addyInsert.Line3); addyInsert.City = objAcctQryOut.ListOfAccount[intIndx].PrimaryBillToCity; q.Enqueue(addyInsert.City); addyInsert.CountyCodeVertex = accountInfo.PrimaryBillToCounty; q.Enqueue(addyInsert.CountyCodeVertex); addyInsert.StateProvinceCodeVertex = accountInfo.PrimaryBillToState; q.Enqueue(addyInsert.StateProvinceCodeVertex);even know? custResponse.CustomerNumber = accountInfo.FuriganaName; q.Enqueue(custResponse.CustomerNumber); custInput.BillingCurrency = accountInfo.CurrencyCode; q.Enqueue(custInput.BillingCurrency); custInput.Email = accountInfo.CustomText1; q.Enqueue(custInput.Email); custInput.TravelPortCustomerTypeCode = accountInfo.AccountType; q.Enqueue(custInput.TravelPortCustomerTypeCode); var count = q.Count; var xml = new XML(); xml.sendAccountInfoXML(q); //xml.sendAccountInfoXML(acctName, addyInsert.CountryCode, addyInsert.Line1, addyInsert.Line2, addyInsert.Line3, acctWebsite); } private void createXML(Queue<string> q) { string saveLoc = #"C:\Users\XML Test\test{0}.xml"; XmlTextWriter writer = new XmlTextWriter(saveLoc, System.Text.Encoding.UTF8); XmlDocument doc = new XmlDocument(); writer.WriteStartDocument(true); writer.Formatting = Formatting.Indented; writer.Indentation = 2; writer.WriteStartElement("HEADER"); createNode(q, writer); writer.WriteEndElement(); writer.WriteEndDocument(); writer.Close(); doc.Save(writer); } private void createNode(Queue<string> q, XmlWriter writer) { Queue<string> x = new Queue<string>(); x.Enqueue("ACCOUNTNAME"); x.Enqueue("BILLINGCOUNTRY"); x.Enqueue("BILLINGLINE1"); x.Enqueue("BILLINGLINE2"); x.Enqueue("BILLINGLINE3"); x.Enqueue("BILLINGCITY"); x.Enqueue("BILLINGCOUNTY"); x.Enqueue("BILLINGSTATE"); x.Enqueue("CUSTOMERNUMBER"); x.Enqueue("BILLINGCURRENCY"); x.Enqueue("CUSTOMEREMAIL"); x.Enqueue("CUSTOMERTYPE"); //x.Enqueue("CUSTOMURL"); writer.WriteStartElement("ACCOUNTINFO"); for (int i = 0; i < x.Count; i++) { writer.WriteStartElement(x.Dequeue()); for (int j = 0; j < q.Count; j++) { writer.WriteString(q.Dequeue()); writer.WriteEndElement(); } } writer.WriteEndElement(); } However, I feel that the nested loops are not properly functioning. Would you mind trying to guide me through it and point out where I'm messing up? Thank you.
WPF: Join Images in a Single File
My name's Lucas and I'm learning about WPF/C#. I would like to join several images in a single file, as well as a game that use multiple textures that are all in one file, but I have no idea how to do. Could anyone help me at least to think how to do? //Convert Image to Byte[] public byte[] getByteFromImage() { byte[] imageArray = File.ReadAllBytes(op.FileName); return imageArray; } //Convert Byte[] to Image public void getImageFromByte() { FileStream f = new FileStream("escudos.bcf", FileMode.Open); BinaryReader b = new BinaryReader(f); Int64 c = f.Length+1; MemoryStream ms = new MemoryStream(b.ReadBytes(int.Parse(c.ToString()))); Image image = new Image(); image.Source = BitmapFrame.Create(ms, BitmapCreateOptions.None, BitmapCacheOption.OnLoad); imgPatch2.Source = image.Source; f.Dispose(); } //Create Binary File public void save(byte[] img) { FileStream f; if (!File.Exists("escudos.bcf")) { f = new FileStream("escudos.bcf", FileMode.Create); } else { f = new FileStream("escudos.bcf", FileMode.Append); } BinaryWriter b = new BinaryWriter(f); b.Write(img); b.Close(); f.Dispose(); } I thought in doing so, create a file and store it in binary images. Until I got that part, but as this file will have multiple images in binary, I do not know how to pick just one binary image. public void xmlCreate(string name, Int64 ini, Int64 fin) { if (!File.Exists("Escudos.xml")) { XmlTextWriter w = new XmlTextWriter("Escudos.xml", System.Text.Encoding.UTF8); w.Formatting = Formatting.Indented; w.WriteStartDocument(); w.WriteStartElement("Time"); w.WriteStartElement(name); w.WriteElementString("Inicio", ini.ToString()); w.WriteElementString("Fim", fin.ToString()); w.WriteEndElement(); w.WriteEndDocument(); w.Close(); } else { XDocument doc = XDocument.Load("Escudos.xml"); doc.Root.Add(new XElement(name)); doc.Root.Element(name).Add(new XElement("Inicio", ini.ToString())); doc.Root.Element(name).Add(new XElement("Fim", fin.ToString())); doc.Save("Escudos.xml"); } } Now I have created an xml file to store the start and end of the bytes. I can add only when I create a new xml file, I can not get a xml created and add new bytes. When I go to load the xml file gives an error message. " An unhandled exception of type 'System.Xml.XmlException' occurred in System.Xml.dll Additional information: '>' is an unexpected token. The expected token is '='. Line 3, position 15. " UPDATE when I'm reading the bytes to form an image, always the same way, even I adding different images. I'll add code below //Add Image private void btAddImage_Click(object sender, RoutedEventArgs e) { OpenFileDialog op = new OpenFileDialog(); op.Title = "Selecione a Imagem"; op.Filter = "All supported graphics|*.jpg;*.jpeg;*.png|" + "JPEG (*.jpg;*.jpeg)|*.jpg;*.jpeg|" + "Portable Network Graphic (*.png)|*.png"; if (op.ShowDialog() == true) { imgPatch.Source = new BitmapImage(new Uri(op.FileName)); txtName.Focus(); } } //Convert Image private void btConvertImage_Click(object sender, RoutedEventArgs e) { if (String.IsNullOrEmpty(txtName.Text)) { txtName.Focus(); MessageBox.Show("Preencha o Nome", "Error"); } else { save(ConvertFileToByteArray(op.FileName), txtName.Text); } } //Image to Byte Array private static byte[] ConvertFileToByteArray(String FilePath) { return File.ReadAllBytes(FilePath); } //Save Binary File and XML File public void save(byte[] img, string nome) { FileStream f; long ini, fin = img.Length; if (!File.Exists("Escudos.bcf")) { f = new FileStream("Escudos.bcf", FileMode.Create); ini = 0; } else { f = new FileStream("Escudos.bcf", FileMode.Append); ini = f.Length + 1; bin = new TestBinarySegment(); } bin.LoadAddSave("Escudos.xml", "Brasileiro", nome, ini, fin); BinaryWriter b = new BinaryWriter(f); b.Write(img); b.Close(); f.Dispose(); } //Load Image from Byte private void btLoad_Click(object sender, RoutedEventArgs e) { getImageFromByte(); } //Byte to Image public void getImageFromByte(int start, int length) { using (FileStream fs = new FileStream("Escudos.bcf", FileMode.Open)) { byte[] iba = new byte[fs.Length+1]; fs.Read(iba, start, length); Image image = new Image(); image.Source = BitmapFrame.Create(fs, BitmapCreateOptions.None, BitmapCacheOption.OnLoad); imgPatch2.Source = image.Source; } } Thanks
You have a binary file where its contents are segments and each segment contains the binary information needed to create an image. You need to store the starting index and length of each segment so that you can retrieve it. One way to do this is with an xml file. To begin, create a container class for the segments. It looks like this... public class BinarySegment { private const string FileName = "SegmentData.xml"; private static XmlSerializer serializer = new XmlSerializer(typeof(List<BinarySegment>)); public string SegmentName { get; set; } public long SegmentStartIndex { get; set; } public long SegmentLength { get; set; } public static List<BinarySegment> LoadFromFile() { if (!File.Exists(FileName)) { throw new Exception("File must be created first"); } try { using (StreamReader sr = new StreamReader(FileName)) { return serializer.Deserialize(sr) as List<BinarySegment>; } } catch { throw new Exception("File as become corrupted"); } } public static void Save(List<BinarySegment> list) { try { using (StreamWriter sw = new StreamWriter(FileName)) { serializer.Serialize(sw, list); } } catch { throw; } } } There is one instance of this class for each image in your binary file. It will read/write a List of BinarySegments. To test the class, create a test class like this... public class TestBinarySegment { public TestBinarySegment() { List<BinarySegment> myBinarySegments = new List<BinarySegment>(); myBinarySegments.Add(new BinarySegment{SegmentName = "Segment1", SegmentStartIndex = 0, SegmentLength = 1111}); myBinarySegments.Add(new BinarySegment { SegmentName = "Segment2", SegmentStartIndex = 1111, SegmentLength = 1111 }); myBinarySegments.Add(new BinarySegment { SegmentName = "Segment3", SegmentStartIndex = 2222, SegmentLength = 1111 }); BinarySegment.Save(myBinarySegments); } public void LoadAddSave() { List<BinarySegment> myBinarySegments = BinarySegment.LoadFromFile(); myBinarySegments.Add(new BinarySegment { SegmentName = "Segment4", SegmentStartIndex = 333330, SegmentLength = 1111 }); BinarySegment.Save(myBinarySegments); } } This class shows how to create the list and to save it. It also shows how to add new segments and resave the xml file. When the test is run, you get a file like this... <?xml version="1.0" encoding="utf-8"?> <ArrayOfBinarySegment xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <BinarySegment> <SegmentName>Segment1</SegmentName> <SegmentStartIndex>0</SegmentStartIndex> <SegmentLength>1111</SegmentLength> </BinarySegment> <BinarySegment> <SegmentName>Segment2</SegmentName> <SegmentStartIndex>1111</SegmentStartIndex> <SegmentLength>1111</SegmentLength> </BinarySegment> <BinarySegment> <SegmentName>Segment3</SegmentName> <SegmentStartIndex>2222</SegmentStartIndex> <SegmentLength>1111</SegmentLength> </BinarySegment> <BinarySegment> <SegmentName>Segment4</SegmentName> <SegmentStartIndex>333330</SegmentStartIndex> <SegmentLength>1111</SegmentLength> </BinarySegment> </ArrayOfBinarySegment> To run the test, use code like this... TestBinarySegment test = new TestBinarySegment(); test.LoadAddSave(); This shows how to use xml serialization to create a file and add new segments to it. You will need to test this concept and then integrate it into your project.