I have a file "a.txt" which contains the following lines:
14,15,16,17
13,16,15,14
15,17,12,13
...
...
I know that each line will always have 4 columns.
I have to read this file and split the lines based on delimiter (here it is ",") and write the value of each column in its corresponding file i.e. if value in a column is 14 then it has to be dumped/wriiten in 14.txt, if its 15 then it will be written in 15.txt and so on.
Here is what I have done till now:
Map <Integer, String> filesMap = new HashMap<Integer, String>();
for(int i=0; i < 4; i++)
{
filesMap.put(i, i+".txt");
}
File f = new File ("a.txt");
BufferedReader reader = new BufferedReader (new FileReader(f));
String line = null;
String [] cols = {};
while((line=reader.readLine()) != null)
{
cols = line.split(",");
for(int i=0;i<4;i++)
{
File f1 = new File (filesMap.get(cols[i]));
PrintWriter pw = new PrintWriter(new BufferedWriter(new FileWriter(f1)));
pw.println(cols[i]);
pw.close();
}
}
So for line number 1 of file "a.txt", I will have to open, write and close files 14.txt,15.txt,16.txt and 17.txt
Again for line number 2, I have to again open,write and close files 14.txt,15.txt,16.txt and a new file 13.txt
So is there any better option in which I don't have to open and close the file which has already been opened earlier.
At the end of the complete operation I will close all the opened files.
Something like this should work:
Map <Integer, PrintWriter> filesMap = new HashMap<>();
...
if(!filesMap.containsKey(cols[i]))
{
//add a new PrintWriter
} else
{
//use the existing one
}
try
Set<String> s = new HashSet<>();
Scanner sc = new Scanner(new File ("a.txt")).useDelimiter("[\n\r,]+");
while(sc.hasNext()) {
String n = sc.next();
if (s.add(n)) {
FileWriter w = new FileWriter(n + ".txt");
w.write(n);
w.close();
}
}
sc.close();
public static void main(String[] args) throws Exception {
FileReader fr = new FileReader("a.txt");
BufferedReader reader = new BufferedReader(fr);
String line = "";
while ((line = reader.readLine()) != null) {
String[] cols = line.split(",");
for (int i = 0; i < 4; i++) {
FileWriter fstream = new FileWriter(cols[i] + ".txt" , true);// true is for appending the data in the file.
BufferedWriter fbw = new BufferedWriter(fstream);
fbw.write(cols[i] + "\n");
fbw.close();
}
}
}
Try this . I think you want to do like this way.
Related
I'm currently working on an assignment and I cannot find any clue to remove the headline from the text file and write the rest into an ArrayList. Can someone help me?
ID,Nama,GajiPokok,JmlAbsensi,JmlIzin
2,Peter,5000000,17,3
1,John,4500000,19,1
3,Linda,10000000,13,7
4,Lucy,7000000,20,0
Here is my code:
BufferedReader in = new BufferedReader(new FileReader("D:\\" + args[0] + ".txt"));
try {
String line = in.readLine();
String data[];
while (line != null){
data = line.split(",");
Staff s = new Staff(){};
s.setID(Integer.parseInt(data[0]));
s.setNama(data[1]);
s.setGajiPokok(Long.parseLong(data[2]));
s.setjmlhAbsensi(Integer.parseInt(data[3]));
s.setjmlhIzin(Integer.parseInt(data[4]));
s.getID();
s.getNama();
s.getGajiPokok();
s.getjmlhAbsensi();
s.getjmlhIzin();
list_Staff.addAll(Arrays.asList(s));
line = in.readLine();
}
in.close();
} catch (IOException e){e.printStackTrace();}
If you want to ignore first line while reading the CSV file then you can simple skip processing of 1st line by calling in.readLine(); twice at the start as shown in below example:
BufferedReader in = new BufferedReader(new FileReader("D:\\" + args[0] + ".txt"));
String line = in.readLine();
line = in.readLine(); //skip fist line and read second line
String data[];
while (line != null){
data = line.split(",");
Staff s = new Staff(){};
s.setID(Integer.parseInt(data[0]));
s.setNama(data[1]);
s.setGajiPokok(Long.parseLong(data[2]));
s.setjmlhAbsensi(Integer.parseInt(data[3]));
s.setjmlhIzin(Integer.parseInt(data[4]));
s.getID();
s.getNama();
s.getGajiPokok();
s.getjmlhAbsensi();
s.getjmlhIzin();
list_Staff.addAll(Arrays.asList(s));
line = in.readLine();
}
Using skip() method of JAVA 8 Streams:
try(BufferedReader in = new BufferedReader(new FileReader("D:\\" + args[0] + ".txt"))) {
Stream<String> lines = in.lines();
List<Staff> staff = lines.skip(1).map(line -> {
Staff s = new Staff();
String data[] = line.split(",");
s.setID(Integer.parseInt(data[0]));
s.setNama(data[1]);
s.setGajiPokok(Long.parseLong(data[2]));
s.setJmlhAbsensi(Integer.parseInt(data[3]));
s.setJmlhIzin(Integer.parseInt(data[4]));
return s;
}).collect(Collectors.toList());
System.out.println(staff);
}
You can declare the following line twice or initialize integer variable and skip the loop if its zero.
String line = in.readLine();
This solution works.
private void readTextFile(String fileName) throws FileNotFoundException {
BufferedReader in = new BufferedReader(new FileReader(fileName));
Stream<String> stream = in.lines();
List<String> answer = stream.collect(Collectors.toList());
// For Pre-Java8
/*for (int i = 1; i < answer.size(); i++) {
System.out.println(answer.get(i));
}*/
// Split afterwards.
Stream<String> ans = answer.stream().filter(p -> !p.equals(answer.get(0)));
ans.forEach(x -> System.out.println(x));
}
I have a CSV file which contains almost 10000 lines of data. I want to split that file into 10 different CSV file based on the total line count, so that each file can contain 1000 lines of data in the order first file should have 1-1000 lines, second file should have 1001-2000 lines and so on. Also, each of those 10 different CSV file should only contain the data from the first column of the parent CSV file. The code which I developed writes the same data (1.e 1-1000 lines) to all of the 10 csv files. I am unable to figure out what is the mistake in the code.
for (int j=1;j<=files;j++){
String inputfile = "C:/Users/Downloads/File.csv";
BufferedReader br = new BufferedReader(new FileReader(inputfile));
FileWriter fstream1 = new FileWriter("C:/Users/Downloads/FileNumber_"+j+".csv");
BufferedWriter out = new BufferedWriter(fstream1);
String strLine = null;
for (i=i+1;i<=(j*lines);i++) { //I Have declared i as static int i = 0 and have already calculated lines and files in other part of code
strLine = br.readLine();
if (strLine!= null) {
String strar[] = strLine.split(",");
out.write(strar[0]);
if(i!=(j*lines)) {
out.newLine(); }
}
}
out.close();
Use this code
import java.io.*;
import java.util.Scanner;
public class csvfilesplit
{
public static void main(String[] args) throws IOException {
int split;
Scanner reader = new Scanner(System.in); // Reading from System.in
System.out.println("\n Enter The count to split each file :-----------");
int s = reader.nextInt();
File folder = new File("file/"); //*** Location of your file
int filecount = 0;
for (File fo :
folder.listFiles()) {
if (fo.isFile()) {
filecount++;}
}
System.out.println("Total source file count is :----------------------- "+filecount+"\n"); //*** Total numbr of orginal file in mentioned folder
String path = folder.getAbsolutePath();
// System.out.println("location=-----------"+path);
File[] listOfFiles = folder.listFiles();
for (int l = 0; l < listOfFiles.length; l++) {
if (listOfFiles[l].isFile()) {
System.out.println("File name Is :-------------------------- " + listOfFiles[l].getName()); //*** File name
BufferedReader bufferedReader = new BufferedReader(new FileReader(path+"/"+listOfFiles[l].getName())); // Read a souce file
String input;
int count = 0;
while((input = bufferedReader.readLine()) != null)
{
count++;
}
System.out.println("File total rows count is :-------------- "+count); //*** Number of row count in the file
split= count/s;
int n = split,z=0;
if(n!=z)
{
System.out.println("Each splitted file line count is :------ "+split+"\n"); //*** After splitted file have the rows count
FileInputStream fstream = new FileInputStream(path+"/"+listOfFiles[l].getName()); DataInputStream in = new DataInputStream(fstream);
BufferedReader br = new BufferedReader(new InputStreamReader(in)); String strLine;
for (int j=1;j<=s;j++)
{
File dir = new File(path+"/"+"CSV_DATA_"+j);
dir.mkdir();
File filefolder = new File(path+"/"+"CSV_DATA_"+j);
String folderpath = filefolder.getAbsolutePath();
//********Destination File Location******
FileWriter fstream1 = new FileWriter(folderpath+"/"+listOfFiles[l].getName()+".csv"); //*** Splitted files and file format(.txt/csv.....)
BufferedWriter out = new BufferedWriter(fstream1);
for (int i=1;i<=n;i++)
{
strLine = br.readLine();
if (strLine!= null)
{
out.write(strLine);
if(i!=n)
{
out.newLine();
}
}
}
out.close();
}
in.close();
}
else
{// Below N number of row in this file
System.out.println("\n******************************* Mentioned this file have below - "+s+" rows ****************************** "+listOfFiles[l].getName()+" \n");}
}
}
System.out.println("\n Splitted_CSV_files stored location is : "+path);
}
}
The problem of having same lines in each of 10 csv files is because of the line below in method myFunction
BufferedReader br = new BufferedReader(new FileReader(inputfile));
The logic using variables i,j,lines works perfectly. But every time myFunction is called, br (BufferedReader for input file) is initialized again.
So br.readLine() will start reading from start. And thus having same 1000 lines in each of the 10 csv files.
Hope it helps!
Please find the Below code:-
public static void main(String[] args) throws IOException {
//first read the file
String inputfile = "C:/Users/bohrahas/Desktop/SampleCSVFile.csv";
BufferedReader br = new BufferedReader(new FileReader(inputfile));
//create thje first file which will have 1000 lines
File file = new File("C:/Users/bohrahas/Desktop/FileNumber_"+1+".csv");
FileWriter fstream1 = new FileWriter(file);
BufferedWriter out = new BufferedWriter(fstream1);
String line="";
//count the number of line
int count=1;
int file_Number=2;
while ((line = br.readLine()) != null)
{
//if the line is divided by 1000 then create a new file with file count
if(count % 1000 == 0)
{
File newFile = new File("C:/Users/bohrahas/Desktop/FileNumber_"+file_Number+".csv");
fstream1 = new FileWriter(newFile);
file_Number++;
out = new BufferedWriter(fstream1);
}
if(line.indexOf(",")!=-1)
line=line.substring(0, line.indexOf(","));
out.write(line);
out.newLine();
count++;
}
}
Logic :-
You don't have to read the parent file for every loop. Just load it once i.e create a object once and then process the parent file.
While reading every line of parent get the whole line and just remove the columns except first column.
Till the first "," is always a first column. so remove the string after '',"
if the line traversed count is divided completely by 1000 i.e. 2000,3000,4000....etc. create a new file and create a BufferWriter for that.
Your logic is very bad here. I rewrote the whole code for you,
import java.io.*;
import java.util.Scanner;
public class FileSplit {
public static void myFunction(int lines, int files) throws FileNotFoundException, IOException{
String inputfile = "file.csv";
BufferedReader br = new BufferedReader(new FileReader(inputfile)); //reader for input file intitialized only once
String strLine = null;
for (int i=1;i<=files;i++) {
FileWriter fstream1 = new FileWriter("FileNumber_"+i+".csv"); //creating a new file writer.
BufferedWriter out = new BufferedWriter(fstream1);
for(int j=0;j<lines;j++){ //iterating the reader to read only the first few lines of the csv as defined earlier
strLine = br.readLine();
if (strLine!= null) {
String strar[] = strLine.split(",");
out.write(strar[0]); //acquring the first column
out.newLine();
}
}
out.close();
}
}
public static void main(String args[])
{
try{
int lines = 2; //set this to whatever number of lines you need in each file
int count = 0;
String inputfile = "file.csv";
File file = new File(inputfile);
Scanner scanner = new Scanner(file);
while (scanner.hasNextLine()) { //counting the lines in the input file
scanner.nextLine();
count++;
}
System.out.println(count);
int files=0;
if((count%lines)==0){
files= (count/lines);
}
else{
files=(count/lines)+1;
}
System.out.println(files); //number of files that shall eb created
myFunction(lines,files);
}
catch (FileNotFoundException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
}
}
I want to read csv file with BufferedReader and split with StringTokenizer. However there is one line in file which contains this line :
ide,12,office,,3208.83,0.18,577.5,4876
Also here is my read method;
public void readFromCSV(){
try {
File file = new File(myFile);
br = new BufferedReader(new FileReader(file));
String line = null;
while((line = br.readLine()) != null) {
st1 = new StringTokenizer(line,"\n");
while(st1.hasMoreTokens()) {
oneLineList = new ArrayList<>();
st2 = new StringTokenizer(st1.nextToken(),",");
for(int i = 0; i < 8; i++) {
oneLineList.add(st2.nextToken());
}
dataList.add(counter,oneLineList);
}
counter++;
}
br.close();
}catch(IOException ex) {
ex.printStackTrace();
}
}
In for statement, there are 8 fields in each line, and dataList is a two-dimensional array list.
I cannot read whole data because of one line contain consecutive coma, how should I do for fix this?
I want the results from 'name' and 'code' to be inserted into log.txt file, but if I run this program only the name results gets inserted into .txt file, I cannot see code results appending under name. If I do System.outprintln(name) & System.outprintln(code) I get results printed in console but its not being inserted in a file.Can someone tell me what am I doing wrong?
Scanner sc = new Scanner(file, "UTF-8");
BufferedReader br = new BufferedReader(new FileReader(file));
PrintWriter out = new PrintWriter(new FileWriter("log.txt", true));
while ((line = br.readLine()) != null) {
if (line.contains("text1")) {
String[] splits = line.split("=");
String name = splits[2];
for (int i = 0; i < name.length(); i++) {
out.println(name);
}
}
if (line.contains("text2")) {
String[] splits = line.split("=");
String code = splits[2];
for (int i = 0; i < code.length(); i++) {
out.println(code);
}
}
out.close()
}
File looks like:
Name=111111111
Code=333,5555
Category-Warranty
Name=2222222
Code=111,22
Category-Warranty
Have a look at this code. Does that work for you?
final String NAME = "name";
final String CODE = "code";
BufferedReader br = new BufferedReader(new FileReader(file));
PrintWriter out = new PrintWriter(new FileWriter("log.txt", true));
while ((line = br.readLine()) != null) {
String[] splits = line.split("=");
String key = splits[0];
String value = splits[1];
if (key.equals(NAME) || key.equals(CODE)) {
out.println(value);
}
}
out.close();
You have a couple of problems in your code:
you never actually assign the variables name and code.
you close() your PrintWriter inside the while-loop, that means you will have a problem if you read more than one line.
I don't see why this wouldn't work, without seeing more of what you are doing:
BufferedReader br = new BufferedReader(new FileReader(file));
PrintWriter out = new PrintWriter(new FileWriter("log.txt", true));
while ((line = br.readLine()) != null) {
if (line.contains("=")) {
if (line.contains("text1")) {
String[] splits = line.split("=");
if (splits.length >= 2) {
out.println(splits[1]);
}
}
if (line.contains("text2")) {
String[] splits = line.split("=");
if (splits.length >= 2) {
out.println(splits[1]);
}
}
}
}
out.flush();
out.close();
Make sure the second if condition is satisfied i.e. the line String contains "text2".
I have a .txt file with the following content:
1 1111 47
2 2222 92
3 3333 81
I would like to read line-by-line and store each word into different variables.
For example: When I read the first line "1 1111 47", I would like store the first word "1" into var_1, "1111" into var_2, and "47" into var_3. Then, when it goes to the next line, the values should be stored into the same var_1, var_2 and var_3 variables respectively.
My initial approach is as follows:
import java.io.*;
class ReadFromFile
{
public static void main(String[] args) throws IOException
{
int i;
FileInputStream fin;
try
{
fin = new FileInputStream(args[0]);
}
catch(FileNotFoundException fex)
{
System.out.println("File not found");
return;
}
do
{
i = fin.read();
if(i != -1)
System.out.print((char) i);
} while(i != -1);
fin.close();
}
}
Kindly give me your suggestions. Thank You
public static void main(String[] args) throws IOException {
File file = new File("/path/to/InputFile");
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
String line = null;
while( (line = br.readLine())!= null ){
// \\s+ means any number of whitespaces between tokens
String [] tokens = line.split("\\s+");
String var_1 = tokens[0];
String var_2 = tokens[1];
String var_3 = tokens[2];
}
}
try {
BufferedReader fr = new BufferedReader(new InputStreamReader(new FileInputStream(file), "ASCII"));
while(true)
{
String line = fr.readLine();
if(line==null)
break;
String[] words = line.split(" ");//those are your words
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
catch(IOException e)
{
e.printStackTrace();
}
Hope this Helps!
Check out BufferedReader for reading lines. You'll have to explode the line afterwards using something like StringTokenizer or String's split.
import java.io.*;
import java.util.Scanner;
class Example {
public static void main(String[] args) throws Exception {
File f = new File("main.txt");
StringBuffer txt = new StringBuffer();
FileOutputStream fos = new FileOutputStream(f);
for (int i = 0; i < args.length; i++) {
txt.append(args[i] + " ");
}
fos.write(txt.toString().getBytes());
fos.close();
FileInputStream fis = new FileInputStream("main.txt");
InputStreamReader input = new InputStreamReader(fis);
BufferedReader br = new BufferedReader(input);
String data;
String result = new String();
StringBuffer txt1 = new StringBuffer();
StringBuffer txt2 = new StringBuffer();
File f1 = new File("even.txt");
FileOutputStream fos1 = new FileOutputStream(f1);
File f2 = new File("odd.txt");
FileOutputStream fos2 = new FileOutputStream(f2);
while ((data = br.readLine()) != null) {
result = result.concat(data);
String[] words = data.split(" ");
for (int j = 0; j < words.length; j++) {
if (j % 2 == 0) {
System.out.println(words[j]);
txt1.append(words[j] + " ");
} else {
System.out.println(words[j]);
txt2.append(words[j] + " ");
}
}
}
fos1.write(txt1.toString().getBytes());
fos1.close();
fos2.write(txt2.toString().getBytes());
fos2.close();
br.close();
}
}