I need to read a file, which has an "n" number of lines, I need to know when reading the end of each line, so I can store the line in an array, ok so far I have
while(stream.position < stream.bytesAvailable)
{
char = stream.readUTFBytes(1);
if(char == "\n")
{
array.push(line);
line = "";
}
else
{
line += char;
}
}
my question is, always the end of line will be "\n"?? how can I be sure if is not an other character like \r??, there is an other character for end of line??, thanks for any help!!!
How about something like this:
var lines:Array = stream.readUTF().split('\r\n').join('\n').split('\n');
It reads the entire string from the file and then first splits on windows line endings, replacing them with unix line endings. It then splits again on unix line endings. The result should be an array containing all of the lines...
Since you're reading the whole stream anyway, putting it into memory, why not just load it into a string and then split the string into lines at that point. You can test the string first for \n or \r or the combination of \r\n (which you should test for first).
Example, where myFileString is what you've read in:
var lineEnding = ''; // String var for storing line ending char or char combo
var lines = []; // Array var for storing the lines of the string
if (myFileString.match('\r\n') {
lineEnding = '\r\n';
} else if (myFileString.match('\r') {
lineEnding = '\r';
} else if (myFileString.match('\n') {
lineEnding = '\n';
}
if (lineEnding != '') {
lines = myFileString.split(lineEnding); // here are your lines
} else {
lines[0] = myFileString; // it's one line
}
Related
I need your help friends
I wrote a code that will extract records from SQL TABLE and use dataset to write it to XML, but i encounter a date convertion challenge after writting the XML the date change from dd/mm/yyyy to yyyy-mm-ddT00:00:00+00, in the process of correcting this, i found this code www.c-sharpcorner.com
//XMLTextReader
//Reads the Xml data generated by DataSet
XmlTextReader XTReader = new XmlTextReader(ds1.GetXml(),
XmlNodeType.Element, null);
//XMLTextWriter
//To write data into xml file
XmlTextWriter XTWriter = new XmlTextWriter(directoryPath + Tfilename.Trim() + ".xml", Encoding.UTF8);
XTWriter.WriteStartDocument();
string fieldName = "";
while (XTReader.Read())
{
switch (XTReader.NodeType)
{
//Check for the Node Name
case XmlNodeType.Element:
XTWriter.WriteStartElement(XTReader.Name);
fieldName = XTReader.Name;
break;
//Check for the Node Value
case XmlNodeType.Text:
//If the NodeName is PubDate
string Fname = "";
foreach (string mList in mFieldname)
{
Fname = mList.ToString().ToLower();
if (fieldName.ToLower() == Fname)
break;
}
if (fieldName.ToLower() == Fname)
//if (fieldName.ToLower() == SearchDate.ToLower())
{
DateTime dt = DateTime.Parse(XTReader.Value.ToString());
//Here the DateTime can be changed to any format as
//MM-dd-yyyy or dd-MM-yyyy or .ToShortDateString() ...
XTWriter.WriteString(dt.ToString("dd/MM/yyyy"));
}
else
XTWriter.WriteString(XTReader.Value);
// break;
//}
break;
case XmlNodeType.EndElement:
XTWriter.WriteEndElement();
break;
} //switch
} // while
XTWriter.Close();
this code worked fine in converting the date to british-UK format, The issue now is, it is changing the XML file from vertical arrengment to horizontal making it hard to read. Bellow is the result:
<?xml version="1.0" encoding="utf-8"?><NewDataSet> <PatientDemographics_Record><Lastname>Hidden</Lastname> <Firstname>Hidden</Firstname><ClinicalVisit6MonthsPriorToReview>Yes</ClinicalVisit6MonthsPriorToReview><MaritalStatus>MARRIED</MaritalStatus><HosiptalNo>Null</HosiptalNo><RNL_SerialNO>263</RNL_SerialNO><Gender>Male</Gender><DateofBirth>11/01/1976</DateofBirth><AGE>40</AGE><HospitalAdmissionDuringReview>Null</HospitalAdmissionDuringReview><Occupation>Employed</Occupation><Education>Junior Secondary</Education><WardVillageTown_OfResidence><LGA_OfResidence>UDI</LGA_OfResidence><State_OfResidence>ENUGU</State_OfResidence><State_OfOrigin>ENUGU</State_OfOrigin><Tribe>IBO</Tribe><FacilityID>1416110036</FacilityID><PatientID>02371</PatientID><DateEnrolled>28/05/2015</DateEnrolled><RecordCompletionPosition>16</RecordCompletionPosition><UploaderId>Null</UploaderId><UploaderDT>01/01/1999</UploaderDT><webUploadFlag>NO</webUploadFlag><ReviewPeriod>6</ReviewPeriod><ART_Start_Date>01/07/2015</ART_Start_Date><ptn_pk>5988</ptn_pk></WardVillageTown_OfResidence><PatientDemographics_Record><Lastname>Hidden</Lastname><Firstname>Hidden</Firstname><ClinicalVisit6MonthsPriorToReview>Yes</ClinicalVisit6MonthsPriorToReview><MaritalStatus>MARRIED</MaritalStatus><HosiptalNo>Null</HosiptalNo><RNL_SerialNO>574</RNL_SerialNO><Gender>Male</Gender><DateofBirth>11/04/1979</DateofBirth><AGE>36</AGE><HospitalAdmissionDuringReview>Null</HospitalAdmissionDuringReview><Occupation>Employed</Occupation><Education>Junior Secondary</Education><WardVillageTown_OfResidence>AWKUNTO</WardVillageTown_OfResidence><LGA_OfResidence>UDI</LGA_OfResidence><State_OfResidence>ENUGU</State_OfResidence><State_OfOrigin>ENUGU</State_OfOrigin><Tribe>IBO</Tribe><FacilityID>1416110036</FacilityID><PatientID>02348</PatientID><DateEnrolled>28/04/2015</DateEnrolled><RecordCompletionPosition>16</RecordCompletionPosition><UploaderId>Null</UploaderId><UploaderDT>01/01/1999</UploaderDT><webUploadFlag>NO</webUploadFlag><ReviewPeriod>6</ReviewPeriod><ART_Start_Date>24/11/2015</ART_Start_Date><ptn_pk>5916</ptn_pk></PatientDemographics_Record><PatientDemographics_Record><Lastname>Hidden</Lastname><Firstname>Hidden</Firstname><ClinicalVisit6MonthsPriorToReview>Yes</ClinicalVisit6MonthsPriorToReview><MaritalStatus>MARRIED</MaritalStatus><HosiptalNo>Null</HosiptalNo><RNL_SerialNO>784</RNL_SerialNO><Gender>Female</Gender><DateofBirth>01/03/1990</DateofBirth><AGE>26</AGE><HospitalAdmissionDuringReview>Null</HospitalAdmissionDuringReview><Occupation>Employed</Occupation><Education>Junior Secondary</Education><WardVillageTown_OfResidence><LGA_OfResidence>UDI</LGA_OfResidence><State_OfResidence>ENUGU</State_OfResidence><State_OfOrigin>ENUGU</State_OfOrigin><Tribe>IBO</Tribe><FacilityID>1416110036</FacilityID><PatientID>02287</PatientID><DateEnrolled>17/02/2015</DateEnrolled><RecordCompletionPosition>16</RecordCompletionPosition><UploaderId>Null</UploaderId><UploaderDT>01/01/1999</UploaderDT><webUploadFlag>NO</webUploadFlag><ReviewPeriod>6</ReviewPeriod><ART_Start_Date>20/10/2015</ART_Start_Date><ptn_pk>6470</ptn_pk></WardVillageTown_OfResidence><PatientDemographics_Record><Lastname>Hidden</Lastname><Firstname>Hidden</Firstname><ClinicalVisit6MonthsPriorToReview>Yes</ClinicalVisit6MonthsPriorToReview><MaritalStatus>MARRIED</MaritalStatus><HosiptalNo>Null</HosiptalNo><RNL_SerialNO>842</RNL_SerialNO><Gender>Male</Gender><DateofBirth>15/05/1985</DateofBirth><AGE>30</AGE><HospitalAdmissionDuringReview>Null</HospitalAdmissionDuringReview><Occupation>Employed</Occupation><Education>Junior Secondary</Education><WardVillageTown_OfResidence>ATANI AROCHUKWU</WardVillageTown_OfResidence><LGA_OfResidence>UDI</LGA_OfResidence><State_OfResidence>IMO</State_OfResidence><State_OfOrigin>IMO</State_OfOrigin><Tribe>IBO</Tribe><FacilityID>1416110036</FacilityID><PatientID>01549</PatientID><DateEnrolled>01/11/2011</DateEnrolled><RecordCompletionPosition>16</RecordCompletionPosition><UploaderId>Null</UploaderId><UploaderDT>01/01/1999</UploaderDT><webUploadFlag>NO</webUploadFlag><ReviewPeriod>6</ReviewPeriod><ART_Start_Date>21/07/2015</ART_Start_Date><ptn_pk>4690</ptn_pk></PatientDemographics_Record></PatientDemographics_Record></PatientDemographics_Record></NewDataSet>
Try to set formatting and indentation properties of the XmlTextWriter.
https://msdn.microsoft.com/en-us/library/system.xml.xmltextwriter.formatting(v=vs.110).aspx
https://msdn.microsoft.com/en-us/library/system.xml.xmltextwriter.indentation(v=vs.110).aspx
In your case, add these lines after the creation of XmlTextWriter:
XTWriter.Formatting = Formatting.Indented;
XTWriter.Indentation = 4;
I have a piece of code that opens a HTTP connection to read the data contained on a webpage.
HttpConnection h = new HttpConnection();
InputStream input = h.openInputStream();
int len = (int) h.httpConn.getLength();
StringBuffer raw = new StringBuffer();
if(len > 0)
{
byte[] data = new byte[len];
while( -1 != (len = input.read(data)))
{
raw.append(new String(data, 0, len));
}
}
response = raw.toString();
input.close();
h.httpConn.close();
//System.out.println("Response -----> " + response);
return response;
This code works absolutely fine, but on certain punctuation marks its not reading properly. For example >> ' << an apostrophe comes out as >> รข <<.
I'm guessing it might be something to do with encoding but I have tried UTF-8, UTF-16 and ASCII and this didn't fix the problem.
I've had this work for me when I was getting odd characters in place of punctuation:
public String getContents(InputStream stream) {
String contents = null;
try{
contents = new String(IOUtilities.streamToBytes(stream), "UTF-8");
}
catch(Exception e) {
//encoding error
}
return contents;
}
Instead of this:
raw.append(new String(data, 0, len));
you can use
raw.append(new String(data, 0, len, "UTF-8"));
passing in the name of a character enconding, in this case UTF-8.
how can i convert a string to a Decimal(10,2) in C#?
Take a look at Decimal.TryParse, especially if the string is coming from a user.
You'll want to use TryParse if there's any chance the string cannot be converted to a Decimal. TryParse allows you to test if the conversion will work without throwing an Exception.
You got to be careful with that, because some cultures uses dots as a thousands separator and comma as a decimal separator.
My proposition for a secure string to decimal converstion:
public static decimal parseDecimal(string value)
{
value = value.Replace(" ", "");
if (System.Globalization.CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator == ",")
{
value = value.Replace(".", ",");
}
else
{
value = value.Replace(",", ".");
}
string[] splited = value.Split(System.Globalization.CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator[0]);
if (splited.Length > 2)
{
string r = "";
for (int i = 0; i < splited.Length; i++)
{
if (i == splited.Length - 1)
r += System.Globalization.CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator;
r += splited[i];
}
value = r;
}
return decimal.Parse(value);
}
The loop is in case that string contains both, decimal and thousand separator
Try:
string test = "123";
decimal test2 = Convert.ToDecimal(test);
//decimal test2 = Decimal.Parse(test);
//decimal test2;
// if (decimal.TryParse(test, out result))
//{ //valid }
//else
//{ //Exception }
labelConverted.Text = test2.toString();
Decimal Examples
Difference between Convert.ToDecimal(string) & Decimal.Parse(string)
Regards
I am beginner in JavaME. I'd like to make simple dicitionary. The source data is placed on "data.txt" file in "res" directory. The structure is like this:
#apple=kind of fruit;
#spinach=kind of vegetable;
The flow is so simple. User enters word that he want to search in a text field, e.g "apple", system take the user input, read the "data.txt", search the matched word in it, take corresponding word, and display it to another textfield/textbox.
I've managed to read whole "data.txt" using this code..
private String readDataText() {
InputStream is = getClass().getResourceAsStream("data.txt");
try {
StringBuffer sb = new StringBuffer();
int chr, i=0;
while ((chr = is.read()) != -1)
sb.append((char) chr);
return sb.toString();
}
catch (Exception e) {
}
return null;
}
but I still dont know how to split it, find the matched word with the user input and take corresponding word. Hope somebody willing to share his/her knowledge to help me..
Basically you want something like this:
private String readDataText() {
InputStream is = getClass().getResourceAsStream("data.txt");
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String line;
try {
while ((line = br.readLine()) != null)
{
String[] split = line.split("=");
if (split[0].equals("#someFruit"))
return split[1];
}
}
catch (Exception e) {}
return null;
}
Read the line using a BufferedReader, no need to handle single chars.
Split the line by the = token
Check if the key in the dictionary is the wanted key, if so, return the value.
I am trying to do the following in AIR:
browse to a text file
read the text file and store it in a string (ultimately in an array)
split the string by the delimiter \n and put the resulting strings in an array
manipulate that data before sending it to a website (mysql database)
The text files I am dealing with will be anywhere from 100-500mb in size. So far, I've been able to to complete steps 1 and 2, here is my code:
<mx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
import flash.filesystem.*;
import flash.events.*;
import mx.controls.*;
private var fileOpened:File = File.desktopDirectory;
private var fileContents:String;
private var stream:FileStream;
private function selectFile(root:File):void {
var filter:FileFilter = new FileFilter("Text", "*.txt");
root.browseForOpen("Open", [filter]);
root.addEventListener(Event.SELECT, fileSelected);
}
private function fileSelected(e:Event):void {
var path:String = fileOpened.nativePath;
filePath.text = path;
stream = new FileStream();
stream.addEventListener(ProgressEvent.PROGRESS, fileProgress);
stream.addEventListener(Event.COMPLETE, fileComplete);
stream.openAsync(fileOpened, FileMode.READ);
}
private function fileProgress(p_evt:ProgressEvent):void {
fileContents += stream.readMultiByte(stream.bytesAvailable, File.systemCharset);
readProgress.text = ((p_evt.bytesLoaded/1048576).toFixed(2)) + "MB out of " + ((p_evt.bytesTotal/1048576).toFixed(2)) + "MB read";
}
private function fileComplete(p_evt:Event):void {
stream.close();
//fileText.text = fileContents;
}
private function process(c:String):void {
if(!c.length > 0) {
Alert.show("File contents empty!", "Error");
}
//var array:Array = c.split(/\n/);
}
]]>
</mx:Script>
Here is the MXML
<mx:Text x="10" y="10" id="filePath" text="Select a file..." width="678" height="22" color="#FFFFFF" fontWeight="bold"/>
<mx:Button x="10" y="40" label="Browse" click="selectFile(fileOpened)" color="#FFFFFF" fontWeight="bold" fillAlphas="[1.0, 1.0]" fillColors="[#E2E2E2, #484848]"/>
<mx:Button x="86" y="40" label="Process" click="process(fileContents)" color="#FFFFFF" fontWeight="bold" fillAlphas="[1.0, 1.0]" fillColors="[#E2E2E2, #484848]"/>
<mx:TextArea x="10" y="70" id="fileText" width="678" height="333" editable="false"/>
<mx:Label x="10" y="411" id="readProgress" text="" width="678" height="19" color="#FFFFFF"/>
step 3 is where I am having some troubles. There are 2 lines in my code commented out, both lines cause the program to freeze.
fileText.text = fileContents; attempts to put the contents of the string in a textarea
var array:Array = c.split(/\n/); attempts to split the string by delimiter newline
Could use some input at this point...
Am i even going about this the right way?
Can flex/air handle files this large? (i'd assume so)
This is my first attempt at doing any sort of flex work, if you see other things ive done wrong or could be done better, i'd appreciate the heads up!
Thanks!
Doing a split on a 500MB file might not be a good idea. You can write your own parser to work on the file but it may not be very fast either:
private function fileComplete(p_evt:Event):void
{
var array:Array = [];
var char:String;
var line:String = "";
while(stream.position < stream.bytesAvailable)
{
char = stream.readUTFBytes(1);
if(char == "\n")
{
array.push(line);
line = "";
}
else
{
line += char;
}
}
// catch the last line if the file isn't terminated by a \n
if(line != "")
{
array.push(line);
}
stream.close();
}
I haven't tested it but it should just step through the file character by character. If the character is a new line then push the old line into the array otherwise add it to the current line.
If you don't want it to block your UI while you do it, you'll need to abstract it into a timer based idea:
// pseudo code
private function fileComplete(p_evt:Event):void
{
var array:Array = [];
processFileChunk();
}
private function processFileChunk(event:TimerEvent=null):void
{
var MAX_PER_FRAME:int = 1024;
var bytesThisFrame:int = 0;
var char:String;
var line:String = "";
while( (stream.position < stream.bytesAvailable)
&& (bytesThisFrame < MAX_PER_FRAME))
{
char = stream.readUTFBytes(1);
if(char == "\n")
{
array.push(line);
line = "";
}
else
{
line += char;
}
bytesThisFrame++;
}
// if we aren't done
if(stream.position < stream.bytesAvailable)
{
// declare this in the class
timer = new Timer(100, 1);
timer.addEventListener(TimerEvent.TIMER_COMPLETE, processFileChunk);
timer.start();
}
// we're done
else
{
// catch the last line if the file isn't terminated by a \n
if(line != "")
{
array.push(line);
}
stream.close();
// maybe dispatchEvent(new Event(Event.COMPLETE)); here
// or call an internal function to deal with the complete array
}
}
Basically you choose an amount of the file to process each frame (MAX_PER_FRAME) and then process that many bytes. If you go over the number of bytes then just make a timer to call the process function again in a few frames time and it should continue where it left off. You can dispatch an event of call another function once you are sure you are complete.
I agree.
Try to split the text into chunks while you're reading it from the stream.
This way you don't have to store the text in your fileContents String (reducing the memory usage by 50%)
Try to process it in parts.
With regards to James's homespun parser, there is a problem if the text files contain any multibyte UTF characters (I was trying to parse UTF files in a similar manner when I came across this thread). Converting each byte to an individual string will disintegrate multi-byte characters, so I made some modifications.
In order to make this parser multi-byte friendly, you can store the growing lines in a ByteArray rather than a string. Then when you hit the end of a line (or a chunk, or the file), you can parse it as a UTF string (if necessary) without any problems:
var
out :ByteArray,
line_out :String,
line_end :Number,
char :int,
line:ByteArray;
out = new ByteArray();
line = new ByteArray();
while( file_stream.bytesAvailable > 0 )
{
char = file_stream.readByte();
if( (String.fromCharCode( char ) == "\n") )
{
// Do some processing on a line-by-line basis
line_out = ProcessLine( line );
line_out += "\n";
out.writeUTFBytes( line_out );
line = new ByteArray();
}
else
{
line.writeByte( char );
}
}
//Get the last line in there
out.writeBytes( line );
stream.position < stream.bytesAvailable
Wouldn't this condition be false after the position reaches the middle of the file?
If the file is 10 bytes, after you have read 5 bytes then bytesAvailable will be 5, I stored the initial value in another variable and used it in the condition.
Besides that, I think it is pretty good