reading csv file using scanner in java - java

public void readCases(String filename) throws IOException {
records.clear(); //name of list is records
try (Scanner input = new Scanner(new File(filename))){
input.nextLine();
while (input.hasNext()){
String text = input.nextLine();
String[] element = text.split(",");
for(int i = 0; i<=3; i++){
if(element[i].equals(' ')){
throw new DatasetException("column missing in csv");
}
}
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd-MM-uuuu");
LocalDate date = LocalDate.parse(element[0], formatter);
int europeCases = Integer.parseInt(element[1]);
int asiaCases = Integer.parseInt(element[2]);
int africaCases = Integer.parseInt(element[3]);
CaseRecord caseRecord = new CaseRecord(date, europeCases, asiaCases, africaCases);
addRecord(caseRecord); //this adds caseRecords to records
}
}
}
I am trying to clear an old list, then trying to read a CSV file and loading the list into the list. I'm not really sure where I'm going wrong.
The list contains 4 fields with types
DateTime
int
int
int
and is in the form
2020-10-08,4,41,0
The top line reads
Date,Europe,Asia,Africa
and I want to skip this first line when loading the data into the list.

You can try Java lambda for reading lines of file, skip(1) to skip first line
//read file into stream, try-with-resources
try (Stream<String> stream = Files.lines(Paths.get(fileName))) {
stream.skip(1).forEach(System.out::println);
} catch (IOException e) {
e.printStackTrace();
}

Related

reading comma separated text files of different lengths in java

so I have a text file and i am trying to read line by line and then populate my array list.
a sample text file is shown below:
10,11,11/10/2021,24,1,2
11,12,11/10/2021,1,2,3
12,13,11/10/2021,24,5
13,14,11/10/2021,1,11,32,2
14,15,11/10/2021,1,9,8
I have been able to read in the first 4 elements (ID,ID,date,price)
and then i need to populate the other elements on that line into an array list (all elements after price)
the problem I am having is that it populates all the other lines into the array list and just not the remaining elements for the one line.
here is the code
int ID = 0;
int spareID = 0;
String date = "";
float fee = 0;
ArrayList<String> limits = new ArrayList<String>();
ArrayList<Import> imports= new ArrayList<Imports>();
File myfile = new File("file.txt");
try {
Scanner inputFile = new Scanner(myfile);
inputFile.useDelimiter(",");
// setting comma as delimiter pattern
while (inputFile.hasNextLine()) {
ID = inputFile.nextInt();
SpareID = inputFile.nextInt();
date = inputFile.next();
fee = inputFile.nextFloat();
while (inputFile.hasNext()) {
limits.add(inputFile.next());
}
Import import = new Import(ID, spareID, fee, date, limits);
imports.add(import);
}
inputFile.close();
} catch (FileNotFoundException e) {
System.out.println("error: can not find file");
}
the array list is capturing the rest of the text file when i need it to capture just the remaining elements on that line.
Edit: the first 4 elements of the line will all go into a different variable and then I need the rest or the elements on that line only to go into the array list
Use Scanner.nextLine() to get a single line, then create a second Scanner with that line to parse it contents.
Scanner inputFile = new Scanner(myfile);
while (inputFile.hasNextLine()) {
Scanner line = new Scanner(inputFile.nextLine());
// setting comma as delimiter pattern
line.useDelimiter(",");
ID = line.nextInt();
SpareID = line.nextInt();
date = line.next();
fee = line.nextFloat();
while (line.hasNext()) {
limits.add(line.next());
}
}
inputFile.close();

Add float and string value in a single array and use that to write .CSV file

Am trying to create a .CSV file using float and string values in a single array. And use the array values to write .CSV file (I have many entries ex: > 50,000)
Ist String value...
long _time = (dataValue.getInt(0) & 0xffffffffL);
Date date = new Date(_time*1000L);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
String formattedDate = sdf.format(date); // 2015-07-03 09:48:41
IInd Float value...
float _resistanceValue = dataValue.getFloat(8); // 1.60774944E8
I need to join these two values dynamically {inside the while loop} in an array and using that value to write .CSV file
I have tried to join the values like...
ArrayList updateValue = new ArrayList();
updateValue.add(formattedDate,_resistanceValue);
//(Which I am not successful)
Using the below code to write .CSV file
private static final String FILE_HEADER = "Time,ResistanceValue";
private static final String NEW_LINE_SEPARATOR = "\n";
FileWriter fileWriter = null;
String fileName = "C:\\temp.csv";
FileWriter fileWriter = null;
try {
fileWriter = new FileWriter(fileName);
//Write the CSV file header
fileWriter.append(FILE_HEADER.toString());
//Add a new line separator after the header
fileWriter.append(NEW_LINE_SEPARATOR);
//Write a values of "formattedDate" & "_resistanceValue" into the CSV file
fileWriter.append(updateValue);
System.out.println("CSV file was created successfully !!!");
} catch (Exception e) {
System.out.println("Error in CsvFileWriter !!!");
e.printStackTrace();
} finally {
try {
fileWriter.flush();
fileWriter.close();
} catch (IOException e) {
System.out.println("Error while flushing/closing fileWriter !!!");
e.printStackTrace();
}
}
Please give me a direction to achieve it. Thanks
You have to write each one by one, separated by comma(,) as delimiter as you need csv.
So Instead of this
//Write a values of "formattedDate" & "_resistanceValue" into the CSV file
fileWriter.append(updateValue);
It should be
//for loop to get the data and then for each data ,keep on writing in file.
fileWriter.append(formattedDate);
fileWriter.append(',');
fileWriter.append(_resistanceValue);
fileWriter.append('\n');
I worked around and used long approach to achieve it....
Firstly, declared three lists...
ArrayList<String> addTime = new ArrayList<String>();
ArrayList<String> addRV = new ArrayList<String>();
ArrayList<String> addTimeandRV = new ArrayList<String>();
Adding the appropriate value to it....
addTime.add(loopIncr, formattedDate); //add data&time to list
addRV.add(loopIncr, formattedResistanceValue); // add RV to list
and joined as #naruto's suggestion and write into a file (Worked!!!)...
for(int i = 0; i < addTime.size(); i++) {
addTimeandRV.add(addTime.get(i));
addTimeandRV.add(",");
addTimeandRV.add(addRV.get(i));
addTimeandRV.add(NEW_LINE_SEPARATOR);
}
for (String str : addTimeandRV) {
fileWriter.write(str);
}
I got successful output .CSV file

Java - Create String Array from text file [duplicate]

This question already has answers here:
Java: Reading a file into an array
(5 answers)
Closed 1 year ago.
I have a text file like this :
abc def jhi
klm nop qrs
tuv wxy zzz
I want to have a string array like :
String[] arr = {"abc def jhi","klm nop qrs","tuv wxy zzz"}
I've tried :
try
{
FileInputStream fstream_school = new FileInputStream("text1.txt");
DataInputStream data_input = new DataInputStream(fstream_school);
BufferedReader buffer = new BufferedReader(new InputStreamReader(data_input));
String str_line;
while ((str_line = buffer.readLine()) != null)
{
str_line = str_line.trim();
if ((str_line.length()!=0))
{
String[] itemsSchool = str_line.split("\t");
}
}
}
catch (Exception e)
{
// Catch exception if any
System.err.println("Error: " + e.getMessage());
}
Anyone help me please....
All answer would be appreciated...
If you use Java 7 it can be done in two lines thanks to the Files#readAllLines method:
List<String> lines = Files.readAllLines(yourFile, charset);
String[] arr = lines.toArray(new String[lines.size()]);
Use a BufferedReader to read the file, read each line using readLine as strings, and put them in an ArrayList on which you call toArray at end of loop.
Based on your input you are almost there. You missed the point in your loop where to keep each line read from the file. As you don't a priori know the total lines in the file, use a collection (dynamically allocated size) to get all the contents and then convert it to an array of String (as this is your desired output).
Something like this:
String[] arr= null;
List<String> itemsSchool = new ArrayList<String>();
try
{
FileInputStream fstream_school = new FileInputStream("text1.txt");
DataInputStream data_input = new DataInputStream(fstream_school);
BufferedReader buffer = new BufferedReader(new InputStreamReader(data_input));
String str_line;
while ((str_line = buffer.readLine()) != null)
{
str_line = str_line.trim();
if ((str_line.length()!=0))
{
itemsSchool.add(str_line);
}
}
arr = (String[])itemsSchool.toArray(new String[itemsSchool.size()]);
}
Then the output (arr) would be:
{"abc def jhi","klm nop qrs","tuv wxy zzz"}
This is not the optimal solution. Other more clever answers have already be given. This is only a solution for your current approach.
This is my code to generate random emails creating an array from a text file.
import java.io.*;
public class Generator {
public static void main(String[]args){
try {
long start = System.currentTimeMillis();
String[] firstNames = new String[4945];
String[] lastNames = new String[88799];
String[] emailProvider ={"google.com","yahoo.com","hotmail.com","onet.pl","outlook.com","aol.mail","proton.mail","icloud.com"};
String firstName;
String lastName;
int counter0 = 0;
int counter1 = 0;
int generate = 1000000;//number of emails to generate
BufferedReader firstReader = new BufferedReader(new FileReader("firstNames.txt"));
BufferedReader lastReader = new BufferedReader(new FileReader("lastNames.txt"));
PrintWriter write = new PrintWriter(new FileWriter("emails.txt", false));
while ((firstName = firstReader.readLine()) != null) {
firstName = firstName.toLowerCase();
firstNames[counter0] = firstName;
counter0++;
}
while((lastName= lastReader.readLine()) !=null){
lastName = lastName.toLowerCase();
lastNames[counter1]=lastName;
counter1++;
}
for(int i=0;i<generate;i++) {
write.println(firstNames[(int)(Math.random()*4945)]
+'.'+lastNames[(int)(Math.random()*88799)]+'#'+emailProvider[(int)(Math.random()*emailProvider.length)]);
}
write.close();
long end = System.currentTimeMillis();
long time = end-start;
System.out.println("it took "+time+"ms to generate "+generate+" unique emails");
}
catch(IOException ex){
System.out.println("Wrong input");
}
}
}
You can read file line by line using some input stream or scanner and than store that line in String Array.. A sample code will be..
File file = new File("data.txt");
try {
//
// Create a new Scanner object which will read the data
// from the file passed in. To check if there are more
// line to read from it we check by calling the
// scanner.hasNextLine() method. We then read line one
// by one till all line is read.
//
Scanner scanner = new Scanner(file);
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
//store this line to string [] here
System.out.println(line);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
Scanner scanner = new Scanner(InputStream);//Get File Input stream here
StringBuilder builder = new StringBuilder();
while (scanner.hasNextLine()) {
builder.append(scanner.nextLine());
builder.append(" ");//Additional empty space needs to be added
}
String strings[] = builder.toString().split(" ");
System.out.println(Arrays.toString(strings));
Output :
[abc, def, jhi, klm, nop, qrs, tuv, wxy, zzz]
You can read more about scanner here
You can use the readLine function to read the lines in a file and add it to the array.
Example :
File file = new File("abc.txt");
FileInputStream fin = new FileInputStream(file);
BufferedReader reader = new BufferedReader(fin);
List<String> list = new ArrayList<String>();
while((String str = reader.readLine())!=null){
list.add(str);
}
//convert the list to String array
String[] strArr = Arrays.toArray(list);
The above array contains your required output.

Get the offset of previous line in a file

I'm extracting data from a file line by line into a database and i can't figure out a proper way to flag lines that I've already read into my database.
I have the following code that I use to iterate through the file lines and I attempt to verify
that the line has my flag or else I try to append the flag to the file line
List<String> fileLines = new ArrayList<String>();
File logFile = new File("C:\\MyStuff\\SyslogCatchAllCopy.txt");
try {
RandomAccessFile raf = new RandomAccessFile(logFile, "rw");
String line = "";
String doneReadingFlag = "##";
Scanner fileScanner = new Scanner(logFile);
while ((line = raf.readLine()) != null && !line.contains(doneReading)) {
Scanner s = new Scanner(line);
String temp = "";
if (!s.hasNext(doneReadingFlag)) {
fileLines.add(line);
raf.write(doneReadingFlag.getBytes(), (int) raf.getFilePointer(),
doneReadingFlag.getBytes().length);
} else {
System.err.println("Allready Red");
}
}
} catch (FileNotFoundException e) {
System.out.println("File not found" + e);
} catch (IOException e) {
System.out.println("Exception while reading the file ");
}
// return fileLines;
// MoreProccessing(fileLines);
This code appends the flag to the next line and it overwrites the characters in that position
Any Help ?
When you write to a file, it doesn't insert do you should expect it to replace the characters.
You need to reserve space in the file for information you want to change or you can add information to another file.
Or instead of marking each file, you can store somewhere the lines number (or better the character position) you have read up to.
If you are not restarting your process you can have process read the file as it is appended (meaning you might not need to store where you are up to anywhere)
#Peter Lawrey I did as you said and it worked for me like that:
as follows:
ArrayList<String> fileLines=new ArrayList<String>();
File logFile=new File("C:\\MyStuff\\MyFile.txt");
RandomAccessFile raf = new RandomAccessFile(logFile, "rw");
String line="";
String doneReadingFlag="#";
long oldOffset=raf.getFilePointer();
long newOffset=oldOffset;
while ((line=raf.readLine())!=null)
{
newOffset=raf.getFilePointer();
if(!line.contains(doneReadingFlag))
{
fileLines.add(line);
raf.seek((long)oldOffset);
raf.writeChars(doneReadingFlag);
raf.seek(newOffset);
System.out.println("Line added and flaged");
}
else
{
System.err.println("Already Red");
}
oldOffset=newOffset;
}

Deleting the last line of a file with Java

I have a .txt file, which I want to process in Java. I want to delete its last line.
I need ideas on how to achieve this without having to copy the entire content into another file and ignoring the last line. Any suggestions?
You could find the beginning of the last line by scanning the file and then truncate it using FileChannel.truncate or RandomAccessFile.setLength.
By taking RandomAccessFile you can:
use method seek(long) to jump forward and read those lines. But you won't know exactly how big the jump should be.
to delete last lines you need the position of begin of last line so before reading each line store their file pointer position (method getFilePointer()). Deleting to that position you use setLength(long).
Code would be something like this:
LinkedList<String> lines=null;
int howMuch = 1; // one line to read and delete
try{
RandomAccessFile raf = new RandomAccessFile(inputFileName, "rw");
System.out.println("File Length="+raf.length());
long step = 20; // here I advice to write average length of line
long jump = raf.length()<step*howMuch?
0:
raf.length()-step*howMuch;
raf.seek(jump);
lines = new LinkedList<String>();
LinkedList<Long> pos = new LinkedList<Long>();
Entry<LinkedList<String>,LinkedList<Long>> rLinesRead = getRemainingLines(raf,
new AbstractMap.SimpleEntry<LinkedList<String>,LinkedList<Long>> (lines,pos));
while(rLinesRead.getKey().size()<howMuch){
if(jump<step)
if(jump<=0)
break;
else{
jump=0;
raf.seek(jump);
rLinesRead=getRemainingLines(raf,rLinesRead);
break;
}
else
jump=jump-step;
raf.seek(jump);
rLinesRead=getRemainingLines(raf,rLinesRead);
}
int originalSize=rLinesRead.getKey().size();
lines=rLinesRead.getKey();
pos=rLinesRead.getValue();
for (int i=0;i<originalSize-howMuch;++i){
lines.removeFirst();
pos.removeFirst();
}
if(!pos.isEmpty())
raf.setLength(pos.getFirst()); // before last(from EOF) returned fully read lines in file
}catch(Exception ex){
ex.printStackTrace();
} finally{
try { raf.close(); } catch (Exception e) { e.printStackTrace(); }
}
//returns line to EOF with their begin file pointer positions
private Entry<LinkedList<String>,LinkedList<Long>> getRemainingLines(RandomAccessFile raf,
Entry<LinkedList<String>,LinkedList<Long>> linesAlreadyLoadedFromEnd) throws IOException{
LinkedList<String> pLines = linesAlreadyLoadedFromEnd.getKey();
LinkedList<Long> pPos = linesAlreadyLoadedFromEnd.getValue();
long init=raf.getFilePointer();
String str = raf.readLine();
if(pPos.size()>0?pPos.getFirst()==0:false || str==null)
return linesAlreadyLoadedFromEnd;
LinkedList<String> lines = new LinkedList<String>();
LinkedList<Long> pos = new LinkedList<Long>();
if(init==0L ){
lines.add(str);
pos.add(0L);
}
Long tmpPos = raf.getFilePointer();
while ((str = raf.readLine())!=null && !pPos.contains(tmpPos)){
lines.add(str);
pos.add(tmpPos);
tmpPos = raf.getFilePointer();
}
pLines.addAll(0,lines);
pPos.addAll(0,pos);
return new AbstractMap.SimpleEntry<LinkedList<String>,LinkedList<Long>> (pLines,pPos);
}

Categories