• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 256
  • Last Modified:

Read From a File

Hi,

I have a text file that has fixed length format.

Length 0-64 EmailAddres
Length 64-66 RecordType
Length 66-80 SubType
................................
Lenght 237-264 Filler

I want to read the fields and store them in my Email object:

Class Email{

private String EmailRecord;
private String EmailAddress;
private String  RecordType;
private String SubType;

public Email(String pEmailRecord, String pEmailAddress, String pRecordType, String pSubType) {
  EmailRecord = pEmailRecord;
  EmailAddress = pEmailAddress;
  RecordType = pRecordType;
  SubType = pSubType;
}

// the getters here

}


I am creating a source class that will read the data file and store the records in the Email object...

I need some illustrations on using/reading from file...and storing it is the Email class...

Thanks
_Esam.
0
_Esam
Asked:
_Esam
  • 21
  • 18
  • 8
  • +1
3 Solutions
 
CEHJCommented:
0
 
hoomanvCommented:
byte[] EmailAddres = new byte[64];
byte[] RecordType= new byte[2];
byte[] SubType= new byte[4];

inputStream.read(EmailAddres);
inputStream.read(RecordType);
inputStream.read(SubType);

then convert these byte arrays to Strings
0
 
CEHJCommented:
If you don't need navigability you can read the file into one char (supporting Unicode) record:


FileReader in = new FileReader("records.txt");
char[] record = new char[80];
while ((in.read(record)) > -1) {
      Email em = new EMail(new String(record, 0, 64), new String(xxx), new String(xxxx));
      // Now add it to a collection
      
}
in.close();
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
_EsamAuthor Commented:
These are some input files...
I would not worry much about appending to it .. writing to it.
All I need it just read from it .. then throw it away after a while :)

Interesting,
What is meant by >navigability?
I think I need to navigate.


AND...

How to I read it using the InputStream ?

_Esam
0
 
CEHJCommented:
>>
Interesting,
What is meant by >navigability?
I think I need to navigate.
>>

Ability to navigate around the file, backwards, forwards etc.

Of course, once you've read the file into a collection you can navigate that

>>How to I read it using the InputStream ?

You read text files in Java with a Reader, not an InputStream (see my example)
0
 
hoomanvCommented:
> How to I read it using the InputStream ?
if it has not been written in a specific encoding, you'll be able to read it with InputStream
new FileInputStream(filename);
0
 
_EsamAuthor Commented:
>char[] record = new char[80];
Can you clarify this?

My file can have any arbitraty size...
The total length of each line is maximum of 266 bytes?
The last two are ASCII CR + ASCII LF !

Length 0-64 EmailAddres
Length 64-66 RecordType
Length 66-80 SubType
................................
Lenght 237-264 Filler

The last two are ASCII CR + ASCII LF characters!

Now how do I read the records... ?

_Esam
0
 
_EsamAuthor Commented:
It is just in ACSII..

_Esam
0
 
CEHJCommented:
It's not common for fixed field size files to have CRLF. Why would it need them? You can allow for those though and call trim() on the String you create for each record
0
 
_EsamAuthor Commented:
Is it possible that in my source class...
I somehow read a whole line... (with conversion perhaps) then pass this to the constructor of the Email that takes..
a String and ....?? (Delimeter?) ...?
I am little confused about how to read from a new line?
There are last two characters ASCII CR + ASCII LF?

_Esam.
0
 
hoomanvCommented:
wrap the FileReader into BufferedReader and use readLine() method
0
 
CEHJCommented:
You need to clear up what format your file is in. Is it fixed field size or is each field on a separate line?
0
 
_EsamAuthor Commented:
This is how the file looks like:

testemail10@myemail.com                  01                    001
testemail11@myemail.com                  11                    007
testemail12@myemail.com                  08                    002  


It was mentioned that the last two bytes are CR+LF ; That's all I know so far...


_Esam                                
0
 
hoomanvCommented:
better to use: new Scanner(new File(filename))

while(scanner.hasNext()) {
   email = scanner.next();
   field1 = scanner.next();
   field2 = scanner.next();
}
0
 
hoomanvCommented:
sorry, I forgot they are fixed size
0
 
hoomanvCommented:
however, Im a bit confused about those white spaces between fields,
testemail10@myemail.com                  01                    001

0-64                                                  64-66               66-80
0
 
CEHJCommented:
Scanner in = new Scanner(new FileReader("records.txt"));
while ((in.hasNext()) {
      Email e = new Email(in.next(), in.next(), in.next());
      // Add to collection
}
in.close();

0
 
_EsamAuthor Commented:
I might want to read the whole record in a String and pass that to the Email constructor taking a String...
In this constructor, I can extract the values based on the field lenghts...that's what I was thinking...like..


public static final int fEmailAddress_Length = 64;
public static final int fEmailAddress_Start = 0;
public static final int fEmailAddress_End = fEmailAddress_Start + fEmailAddress_Length;

public Email(String pDataLine){
mEmailRecord = pDataLine.trim(); //this is the whole line read
mEmailAddress =
                    mEmailRecord.substring
                    (fEmailAddress_Start,
                     fEmailAddress_End).trim(); //this is the first field mapped to EmailAddres instance variable???

}

Let me know...

_Esam
0
 
CEHJCommented:
No, that's not necessary (see my last example)
0
 
_EsamAuthor Commented:
> however, Im a bit confused about those white spaces between fields,
That's how I was told they gonna look like :)

_Esam
0
 
_EsamAuthor Commented:
>No, that's not necessary (see my last example)

FileReader in = new FileReader("records.txt");
char[] record = new char[80];
while ((in.read(record)) > -1) {
     Email em = new EMail(new String(record, 0, 64), new String(xxx), new String(xxxx));
     // Now add it to a collection
     
}
in.close();

Can you explain the > char[] record = new char[80];

Thanks..
_Esam
0
 
CEHJCommented:
>>That's how I was told they gonna look like :)

It's a redundant storage structure. CSV would have been better
0
 
CEHJCommented:
>>Can you explain the > char[] record = new char[80];

That was because you told us initially that you had a fixed record size. Of course, you still do, but you've also got line feeds. btw, that wasn't my last example (the one that would be better)
0
 
_EsamAuthor Commented:
What would be the better approach then?

Thax
_Esam
0
 
hoomanvCommented:
> What would be the better approach then?
fixed size --> readLine() and then cut it into pieces (fixed size fileds)
else --> Scanner
0
 
_EsamAuthor Commented:
How do I give it the File location?

If I say
> mDataFileReader =
             new BufferedReader(new FileReader("Feedback.txt"));

Where do I keep the Feedback.txt file???


_Esam.
0
 
hoomanvCommented:
> Where do I keep the Feedback.txt file???
in current working directory

or you can provide full path like
new FileReader("C:\directory\Feedback.txt")
0
 
CEHJCommented:
>>
or you can provide full path like
new FileReader("C:\directory\Feedback.txt")
>>

that should be

or you can provide full path like
new FileReader("C:/directory/Feedback.txt")

or it wouldn't compile
0
 
_EsamAuthor Commented:
Can It be in any subdirectory of the current working directory?    /Email/data ?

Or can I give it any relative directory from the root directory?  Like /apps/Email/data ?
0
 
_EsamAuthor Commented:
Ok, I read a line, how do I cut it to pieces?

>fixed size --> readLine() and then cut it into pieces (fixed size fileds)


_Esam
0
 
CEHJCommented:
>>Can It be in any subdirectory of the current working directory?    /Email/data ?

Yes, although that should be ./Email/data

>>Or can I give it any relative directory from the root directory?  Like /apps/Email/data ?

Yes

>>Ok, I read a line, how do I cut it to pieces?

You don't need to. The scanner will do it
0
 
_EsamAuthor Commented:
I plan not to use scanner...
I am stuck with 1.4 ..

Just want to read a BufferedReader - FileReader..

_Esam.
0
 
CEHJCommented:
OK. Then you can use

String line = bufferedReader.readLine();
String[] tokens = line.split("\\s+");
EMail em = new EMail(tokens[0], tokens[1], tokens[2]);
0
 
CEHJCommented:
Correction:

String line = null;
while ((line = bufferedReader.readLine()) != null) {
    String[] tokens = line.split("\\s+");
    EMail em = new EMail(tokens[0], tokens[1], tokens[2]);
}
0
 
_EsamAuthor Commented:
> String[] tokens = line.split("\\s+");

Can you explain?? How this works?

Thanks.
_Esam
0
 
CEHJCommented:
It's a regular expression that splits the line on a whitespace delimiter
0
 
_EsamAuthor Commented:
Thanks...I thought so... s for space ?
Why ("\\s+") not ("\\s") ? what is the + for?

_Esam...
0
 
_EsamAuthor Commented:
Now I need little more elaboration on this: (I had to increase the points for fairness)>

I would really like to Keep the Main class (now main but soon just another reader class) as less messy as possible.

While reading each line:

I would like to pass this line to a constructor of the Email that takes a String....that calls another constructor that takes the String and my default delimeter (perhaps from an Interface constant).

In the Main class I just want to call the Email with the String line ... this should construct the object in the Email class..

How do I modularize this???

Sorry if it's too ..

_Esam...

0
 
CEHJCommented:
>>Why ("\\s+") not ("\\s") ? what is the + for?

Match as much consecutive whitespace as possible

>>that calls another constructor that takes the String and my default delimeter (perhaps from an Interface constant).

Just move the method i gave you elsewhere
0
 
_EsamAuthor Commented:
I have a potential problem with using whitespace delimiter!
Although my data look like to be separated by white space, it is not essentially the case.

Here is a snapshot,

testemail4@myemail.com                    01007                     www@yahoo.com  MM/DD/YYYY HH:MM:SS


Here, the second and third field is found together? (second field is 01 and third field is 007)
Because it is a fixed lenght field.

How do I take care of this?

This is why I said the fields are fixed length...

Let me know....            

Thax..
_Esam  
0
 
CEHJCommented:
OK. Then you can do something like

String line = null;
while ((line = bufferedReader.readLine()) != null) {
    char[] fields = line.toCharArray();
    EMail em = new EMail(new String(fields, 0, 64).trim(), new String(fields, 64, 2).trim(), new String(fields, 66, 2).trim());
}
0
 
_EsamAuthor Commented:
Yes, this loooks better!

Let me try and get back to this!

Thax.
_Esam
0
 
_EsamAuthor Commented:
Problem,
When I simply print the string.. it is printing it..
But when I try to extract the field values and store them in the collection and then print it,, not working .

EMail em = new EMail(new String(fields, 0, 64).trim(), new String(fields, 64, 2).trim(), new String(fields, 66, 2).trim());

How is it interpreted?
String (fields, 0, 64) >> 0 is the offset (or the starting index), 64 is the length?

Thanks
_Esam

0
 
CEHJCommented:
>>
How is it interpreted?
String (fields, 0, 64) >> 0 is the offset (or the starting index), 64 is the length?
>>

Correct

>>But when I try to extract the field values and store them in the collection and then print it,, not working .

Not sure how you did that, but i would firstly give your EMail class a toString method and check it immediately thus:


EMail em = new EMail(new String(fields, 0, 64).trim(), new String(fields, 64, 2).trim(), new String(fields, 66, 2).trim());
System.out.println(em);

Whatever collection you have (let's imagine a Set) should then print thus:

System.out.println(setOfEMail);


0
 
JoeCommented:
There are several API's on SourceForge that make this job MUCH easier.  Here is one of them...


http://sourceforge.net/projects/pzfilereader


Joe
0
 
_EsamAuthor Commented:
>Not sure how you did that, but i would firstly give your EMail class a toString method and check it immediately thus:

I did give it a toString, and it did work.
But I need to know what is wrong here:

Email lem;                               //the email object

ArrayList lDataArrayList;            //to add the objects
      
String lDataLine = null;             //line read from the file
      
Email[] lEmailRecords;              //arrays of Email objects

First, I read a line and passed it to the Email constructor, and I extracted the field values there:
 lem = new Email(lDataLine);

I added to the ArrayList:

lDataArrayList.add(lem);

I created an array of Email objects:

lEmailRecords = new Email[lDataArrayList.size()];

I got the values back:

lEmailRecords = ( Email[] ) lDataArrayList.toArray(lEmailRecords);

I wanted to print Like:

for (int i = 0; i < lEmailRecords.length; i++){
                  System.out.println(" " + lEmailRecords[i].getEmailAddress());
                  System.out.println(" " + "In print()");
            }

The reason I created an array of type of the class is not so obvious to me:

This is what I need to do:

I have a class the has a set method that takes an array of objects like:

public void setMessaages(Object []  multilpleMessages) ---

Is there any better way to hold the arrays of these objects ... to set it in this set method..... and later..
extract them with  a get method???

Thanks

_Esam.
0
 
_EsamAuthor Commented:
Ok..Well done ... Greate help..
I needed to close the question!

I need to ask another question related to this one...

Thanks all...
_Esam
0
 
CEHJCommented:
:-)
0

Featured Post

Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

  • 21
  • 18
  • 8
  • +1
Tackle projects and never again get stuck behind a technical roadblock.
Join Now