I am trying to split text files in a directory along a line 'END OF CUSTOMER STATEMENT' and I store the result files into a temporary directory. The split happens only for the first file while the other file is ignored, what is the problem with my code. I was expecting the for loop will engulf all the files in the directory? Here is my code.
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
/**
*
* #author Administrator
*/
public class SplitFiles {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
File f = new File("D:/statements/");
String[] filenames = f.list();
File[] texts = f.listFiles();
String lines = "";
for (int m = 0; m < filenames.length; m++) {
try {
int count = 0;
FileInputStream fs = new FileInputStream("D:/statements/" + filenames[m]);
BufferedReader br = new BufferedReader(new InputStreamReader(fs));
FileOutputStream fos = new FileOutputStream("D:/DFCU Statements/statement" + count + ".RPT");
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(fos));
while ((lines = br.readLine()) != null) {
String mine = lines.trim();
if (mine.startsWith("END OF CUSTOMER STATEMENT")) {
bw.close();
count++;
fos = new FileOutputStream("D:/DFCU Statements/statement" + count + ".RPT");
bw = new BufferedWriter(new OutputStreamWriter(fos));
continue;
}
if (mine.isEmpty()) {
continue;
} else {
bw.write(lines);
bw.newLine();
bw.flush();
}
}
fos.close();
fs.close();
br.close();
bw.close();
} catch (Exception ag) {
System.out.println(ag);
}
}
}
}
I think you should do this in the first place (there are possibly more bugs)
int count = 0;
for (int m = 0; m < filenames.length; m++) {
...
UPDATE besides, remove your count++ and place it after each file creation
FileOutputStream fos = new FileOutputStream("D:/DFCU Statements/statement" + count + ".RPT");
count++;
then it will work as expected
I assume that since the target files have nothing that distinguishes them from each other (they are all named statementX.RPT) - that the last file is actually the one you have in your output - but this is only a guess.
try to change your output file to be named "statement." + m + "." + count ".RPT" and that way you will have unique output files.
Also, take note to the following comments:
When using the File class, the listFiles API is more usefull (in my opinion) - from each file you get you can query getName and getPath.
About this line: FileInputStream fs = new FileInputStream("D:/statements/" + filenames[m]); - if you used the results you got from listFiles you could replace it with FileInputStream fs = new FileInputStream(files[m]); - no need to hard-code the path.
You should modify your code. Otherwise instead of creating two output files your code will create three output files. Here is the correct code
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
/**
*
* #author Administrator
*/
public class SplitFiles {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
File f = new File("D:/statements/");
String[] filenames = f.list();
File[] texts = f.listFiles();
String lines = "";
int count = 0;
for (int m = 0; m < filenames.length; m++) {
try {
FileInputStream fs = new FileInputStream("D:/statements/" + filenames[m]);
BufferedReader br = new BufferedReader(new InputStreamReader(fs));
FileOutputStream fos = null;
BufferedWriter bw = null;
while ((lines = br.readLine()) != null) {
String mine = lines.trim();
if (mine.startsWith("END OF CUSTOMER STATEMENT")) {
if(bw!=null)
{
bw.close();
}
count++;
continue;
}
if (mine.isEmpty()) {
continue;
} else {
if(bw==null)
{
fos = new FileOutputStream("D:/DFCU Statements/statement" + count + ".RPT");
bw = new BufferedWriter(new OutputStreamWriter(fos));
}
bw.write(lines);
bw.newLine();
bw.flush();
}
}
fos.close();
fs.close();
br.close();
bw.close();
} catch (Exception ag) {
System.out.println(ag);
}
}
}
}
Related
Below java code is to split a big .csv file into multiple .csv files. But how to store Header in all splitted files?
import java.io.*;
import java.util.Scanner;
import java.io.File;
import java.io.FileInputStream;
import java.util.Iterator;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
public class split {
public static void main(String args[]) {
try {
String inputfile = "E:/Sumit/csv-splitting-2/Proposal_Details__c.csv";
System.out.println("Input Path is :- " + inputfile);
double nol = 100000.0;
File file = new File(inputfile);
Scanner scanner = new Scanner(file);
int count = 0;
while (scanner.hasNextLine()) {
scanner.nextLine();
count++;
}
System.out.println("Lines in the file: " + count);
double temp = (count / nol);
int temp1 = (int) temp;
int nof = 0;
if (temp1 == temp) {
nof = temp1;
} else {
nof = temp1 + 1;
}
System.out.println("No. of files to be generated :" + nof);
FileInputStream fstream = new FileInputStream(inputfile);
DataInputStream in = new DataInputStream(fstream);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String strLine;
for (int j = 1; j <= nof; j++) {
String outputpath = "E:/Sumit/csv-splitting-2/";
String outputfile = "File-2-Proposal_Details__c" + j + ".csv";
System.out.println(outputpath + outputfile);
FileWriter fstream1 = new FileWriter(outputpath + outputfile);
BufferedWriter out = new BufferedWriter(fstream1);
for (int i = 1; i <= nol; i++) {
strLine = br.readLine();
if (strLine != null) {
out.write(strLine);
if (i != nol) {
out.newLine();
}
}
}
out.close();
}
in.close();
} catch (Exception e) {
System.err.println("Error: " + e.getMessage());
}
}
}
Assuming your first line is the header, you can have a String header; that will get the read of the first line, eg: header = br.readLine();.
On your for loop for nof (which I assume means number_of_files), you always add the header as the first line when you create a new file.
It would be something like this:
before your for-loop, you just save the header on a variable
String header = br.readLine();
you have 2 for-loops, one that creates a file, the other one that write each line to the newly created file
Inside the first for loop, right after you create the file, you just write the header to it: our.write(header);
General tips:
use variable names that makes sense. nol, nof, j... none of them make sense, you can pretty much call them numOfLines, numOfFiles and currentFile for example.
I have a I/O java file, a SDive file which contains main, a .txt Directory file that has random words in it and a Sorted .txt to return the random words in order ascending to descending. It print all the words in the Sorted but it is not sorted.
//Sort.java
// required for input
import java.io.FileReader;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
// required for output
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
class Sort{
private String[] tArr = new String[100];
public void swap(int j) {
String temp = tArr[j-1];
tArr[j-1] = tArr[j];
tArr[j] = temp;
}
///Bubble sort
public void sort() {
int n = tArr.length;
for(int i = 0; i < n; i++) {
for(int j = 1; j < n-i; j++) {
if(tArr[j-1].compareTo(tArr[j]) > 0) {
swap(j);
}
}
}
}
public void read() {
System.out.println("in read()");
String pwd = System.getProperty("user.dir");
String fileName = pwd + "/directory.txt";
System.out.println("Looking for: " + fileName);
String fileLine = "";
try {
File f = new File(fileName);
if(f.exists()) {
System.out.println("Directory profile found, loading data...");
}
else {
System.out.println("Directory profile not found, loading default...");
return; // done, return back to the caller
}
// Read file
FileReader data = new FileReader(fileName);
// Wrap FileReader with BufferedReader
BufferedReader br = new BufferedReader(data);
//String tmp;
int i=0;
while ((fileLine = br.readLine()) != null) {
tArr[i++] = fileLine;
}
// ok, time to load an existing profile
// close the file
br.close();
} catch (FileNotFoundException fnf) {
System.out.println("File not found: " + fileName);
} catch (IOException ioe) {
System.out.println("Error reading file: " + fileName);
} catch (Exception exc) {
System.out.println("Something went wrong: " + fileName);
}
}
public void write() {
System.out.println("in write()");
String pwd = System.getProperty("user.dir");
String fileName = pwd + "/Sorted.txt";
try {
System.out.println("Writing out to: " + fileName);
File file = new File(fileName);
// creates the file
file.createNewFile();
// create FileWriter object
FileWriter writer = new FileWriter(file);
// output to file
// ADD pIdx, pArr, mood, and anything else here...
for(int i = 0; i < tArr.length; i++) {
writer.write(tArr[i] + "\n");
}
writer.flush();
writer.close();
} catch (IOException ex) {
System.out.println("Error writing to file: " + fileName);
}
}
}
And my main file is SDrive:
class SDriver{
public static void main(String args []){
Sort io = new Sort();
io.read();
io.write();
}
}
You should add the io.sort() method after io.read(); line and just before io.write(); line.
I see you use bubble sort, if you really want to implement your own sorting method take a look at quick sort and merge sort which are much much faster than bubble sort on larger arrays but also harder to implement. Insertion and Selection sort are not as fast as merge or quick but still faster than bubble and still as easy to self implement. Or use Arrays.sort(tArr); if you want to do it quick.
I'm working on a Java program in which I must read the contents of a file and then print each lines reverse. For example the text:
Public Class Helloprinter
Public static void
would print the following after running my reverse program:
retnirPolleh ssalc cilbup
diov citats cilbup
Here's what I got so far:
public static void main(String[] args) throws FileNotFoundException {
// Prompt for the input and output file names
ArrayList<String> list = new ArrayList<String>();
//String reverse = "";
Scanner console = new Scanner(System.in);
System.out.print("Input file: ");
String inputFileName = console.next();
System.out.print("Output file: ");
String outputFileName = console.next();
// Construct the Scanner and PrintWriter objects for reading and writing
File inputFile = new File(inputFileName);
Scanner in = new Scanner(inputFile);
PrintWriter out = new PrintWriter(outputFileName);
String aString = "";
while(in.hasNextLine())
{
String line = in.nextLine();
list.add(line);
}
in.close();
for(int i = 0; i <list.size(); i++)
{
aString = list.get(i);
aString = new StringBuffer(aString).reverse().toString();
out.printf("%s", " " + aString);
}
out.close();
}
}
EDIT:
With Robert's posting it helped put me in the right direction. The problem is that with that is that it doesn't keep the lines.
Public Class Helloprinter
Public static void
becomes after running my program:
retnirPolleh ssalc cilbup diov citats cilbup
it needs to keep the line layout the same. so it should be:
retnirPolleh ssalc cilbup
diov citats cilbup
Your problem is in the line
out.printf("%s", " " + aString);
This doesn't output a newline. I'm also not sure why you are sticking a space in there.
It should be either:
out.println( aString );
Or
out.printf("%s%n", aString);
In your last loop why don't you just iterate through the list backwards? So:
for(int i = 0; i <list.size(); i++)
Becomes:
for(int i = list.size() - 1; i >=0; i--)
It seems like you already know how to read a file, so then call this method for each line.
Note, this is recursion and it's probably not the most efficient but it's simple and it does what you want.
public String reverseString(final String s) {
if (s.length() == 0)
return s;
// move chahctrachter at current position and then put it at the end of the string.
return reverseString(s.substring(1)) + s.charAt(0);
}
Just use a string builder. You were on the right trail. Probably just needed a little help. There is no "one way" to do anything, but you could try something like this:
Note: Here is my output: retnirPolleh ssalc cilbup diov citats cilbup
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Scanner;
public class Reverse {
public static void main(String[] args) {
ArrayList<String> myReverseList = null;
System.out.println("Input file: \n");
Scanner input = new Scanner(System.in);
String fileName = input.nextLine();
System.out.println("Output file: \n");
String outputFileName = input.nextLine();
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader(fileName));
String text = null;
myReverseList = new ArrayList<String>();
StringBuilder sb = null;
try {
while ((text = br.readLine()) != null) {
sb = new StringBuilder();
for (int i = text.length() - 1; i >= 0; i--) {
sb.append(text.charAt(i));
}
myReverseList.add(sb.toString());
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Writer writer = null;
try {
writer = new BufferedWriter(new OutputStreamWriter(
new FileOutputStream(outputFileName), "utf-8"));
for (String s : myReverseList) {
writer.write("" + s + "\n");
}
} catch (IOException ex) {
// report
} finally {
try {
writer.close();
} catch (Exception ex) {
}
}
}
}
I have searched the internet to search a chosen directory and use the contained .txt files to convert to .csv to work with the data in a spreadsheet. This program works tried and true with everything .txt and I figured I would share with you all my findings. The only thing left to put in is to limit only .txt files containing LOG in the first letters and it is a complete project for me.
The code is as follows:
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.StringTokenizer;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
public class LogReader
{
/**
*
*/
public static void main(String[] args)
throws IOException
{
// Creates a GUI based chooser for the user to select the directory to
// evaluate.
JFileChooser chooser = new JFileChooser();
chooser.setCurrentDirectory(new File("."));
chooser.setDialogTitle("Folder Chooser");
chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
chooser.setAcceptAllFileFilterUsed(false);
int returnVal = chooser.showOpenDialog(chooser);
if(returnVal == JFileChooser.APPROVE_OPTION)
{
JOptionPane.showMessageDialog(null, "The current directory is:\n"
+ chooser.getSelectedFile().getAbsolutePath());
String sourceFolder = chooser.getSelectedFile().getAbsolutePath();
File folder = new File(sourceFolder);
String temp1;
String temp2 = "\\";
String temp3;
FileWriter output = new FileWriter("Output Log.csv");
BufferedReader reader;
// create list of files within a certain folder.
String[] files = folder.list();
for(int i = 0; i < files.length; i++)
{
if(files[i].lastIndexOf('.') > 0)
{
int lastIndex = files[i].lastIndexOf('.');
String str = files[i].substring(lastIndex);
if(str.equals(".txt"))
{
// Variables to concatenate the complete file directory
// pointer.
temp3 = files[i];
temp1 = sourceFolder.concat(temp2);
temp1 = temp1.concat(temp3);
// Use the BufferedReader with the new file pointer and
// store it
// in line.
reader = new BufferedReader(new FileReader(temp1));
String line = reader.readLine();
while(line != null)
{
StringTokenizer tokens = new StringTokenizer(line,
" ");
while(tokens.hasMoreTokens())
{
String word = tokens.nextToken();
output.append(word + ',');
}
output.append('\n');
// read next line
line = reader.readLine();
}
output.append('\n');
}
}
}
output.flush();
output.close();
// If the user selected cancel, then let them know.
}
else
{
JOptionPane.showMessageDialog(null, "No selection");
}
}
}
I just needed to add a Boolean to this to compare the string with certain requirements.
As in the tittle , i want to write my text from back and enter to the text file . In first , i read the text from the text file , next i want to save it in text file , but writing by the end of. I don't have any ideas how to fix my code . My code read the text file , and write the text file , but in the same order , from beginning to ending.
Example how it must work:
input text:
aaaaa
bbbb
ccc
dd
f
output text:
f
dd
ccc
bbbb
aaaaa
My code:
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
public class Loading {
public static void main(String[] args) {
try {
BufferedReader br = new BufferedReader(new FileReader(
"file.txt.txt"));
String line, txt = "";
String[] splittedLine;
while ((line = br.readLine()) != null) {
txt += linia + "\n";
splittedLine = line.split(" ");
}
System.out.println(txt);
br.close();
BufferedWriter bw = new BufferedWriter(new FileWriter("file2"));
bw.write(txt);
bw.newLine();
bw.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Read File to String
Write String data to File starting from end.
For lines, use String array to store data from file and then traverse from end to start of array.
Here is complete program.
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.util.ArrayList;
import java.util.List;
public class Loading {
public static void main(String[] args) {
try {
BufferedReader br = new BufferedReader(new FileReader(
"DB.xml"));
String line, txt = "";
List<String> lines = new ArrayList<String>();
while ((line = br.readLine()) != null) {
lines.add(line);
}
System.out.println(txt);
br.close();
BufferedWriter bw = new BufferedWriter(new FileWriter("file2"));
for(int i=lines.size()-1; i>=0; i--){
bw.write(lines.get(i));
bw.newLine();
}
bw.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
You're going to want a list of lines, since you don't know the number of entries beforehand, so you want something that can grow with your code.
List<String> lines = new ArrayList<String>();
And add all your lines to it
while ((line = br.readLine()) != null) {
lines.add(line);
}
Then write them to your file in reverse order:
for(int i = lines.size() - 1; i >= 0; i--) {
bw.write(lines.get(i));
bw.newLine();
}
Your code is concatenating the string incorrectly. It needs to add the line text to the beginning of the string rather than at the end if you are trying to reverse the order.
txt = line + txt + "\n"; //original: txt += linia + "\n"
But it would be better to use a StringBuilder object to handle the concatenation for you. Something like...
StringBuilder txt = new StringBuilder();
String line;
while ((line = br.readLine()) != null) {
txt.insert(0, line + "\n");
}
System.out.println(txt.toString());
I do agree that the array approach in the other answers would also work and is probably a little easier to read and maintain. But the StringBuilder approach is closer to what you already have.
It should work:
package test;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.util.ArrayList;
/**
*
* #author
*/
public class Read {
public static void main(String[] args) {
try {
BufferedReader br = new BufferedReader(new FileReader(
"D:/file.txt"));
String line, txt = "";
ArrayList<String> lines = new ArrayList<String>();
while ((line = br.readLine()) != null) {
lines.add(line);
}
System.out.println(txt);
br.close();
BufferedWriter bw = new BufferedWriter(new FileWriter("D:/file2.txt"));
for(int i = lines.size()-1; i>=0; i--){
bw.write(lines.get(i));
bw.newLine();
}
bw.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}