So I'm trying to use a BufferedReader to split a text file into 2 different arrays, I've written some code but I'm not sure where to go from here.
I know how to populate an array, but i just cant seem to get the specific lines.
So, one array for NEW_OFFICE containing only the numbers, and one for MAIN_ADDRESS containing only the numbers below it.
BufferedReader in = null;
try {
in = new BufferedReader(new FileReader("myDelivery.txt"));
String read = null;
while ((read = in.readLine()) != null) {
String words = read.split("NEW_OFFICE")[0];
}
} catch (IOException e) {
System.out.println("There was a problem: " + e);
e.printStackTrace();
} finally {
try {
in.close();
} catch (Exception ignored) { }
}
This is the text file:
NEW_OFFICE
-92.48392883 52.96531732
-2.483984994 92.48392883
MAIN_ADDRESS
-1.207614869 52.98908196
NEW_OFFICE always is the first line, and always has two lines below
it, the same goes for MAIN_ADDRESS it always has one line below it.
NEW_OFFICE & MAIN_ADDRESS can't appear more than once.
Based on your comment mentioned above, given below is the solution:
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.Arrays;
public class Main {
public static void main(String[] args) throws IOException {
String[][] office = new String[2][2];
String[][] main = new String[1][2];
try (BufferedReader in = new BufferedReader(new FileReader("myDelivery.txt"))) {
String read;
while ((read = in.readLine()) != null) {
if (read.equalsIgnoreCase("NEW_OFFICE")) {
// Read next two lines
for (int i = 0; i < 2; i++) {
if ((read = in.readLine()) != null) {
office[i] = read.split("\\s+");
}
}
} else if (read.equalsIgnoreCase("MAIN_ADDRESS")) {
// Read next line
if ((read = in.readLine()) != null) {
main[0] = read.split("\\s+");
}
}
}
}
// Display office[][]
System.out.println("Displaying office:");
for (String[] officeData : office) {
System.out.println(Arrays.toString(officeData));
}
// Display main[][]
System.out.println("Displaying main:");
for (String[] mainData : main) {
System.out.println(Arrays.toString(mainData));
}
}
}
Output:
Displaying office:
[-92.48392883, 52.96531732]
[-2.483984994, 92.48392883]
Displaying main:
[-1.207614869, 52.98908196]
Notes:
\\s+ is for splitting the line on space(s).
Use try-with-resources syntax to simplify your code.
.split() does take a string, but it should be a regex, not the substring that you want to split it on. You want to change your code like this:
try (BufferedReader in = new BufferedReader(new FileReader("x.txt"))) {
String read;
String office = "";
while ((read = in.readLine()) != null) {
if (read.contains("NEW_OFFICE")) {
office = "NEW_OFFICE";
} else if (read.contains("MAIN_ADDRESS")) {
office = "MAIN_ADDRESS";
} else {
System.out.println(office + " : " + read);
}
}
} catch (IOException e) {
e.printStackTrace();
}
I have also changed your try with try-with-resources so you don't have to worry about closing the resource.
I´d go with somethin like this.
Please be aware that I don´t have an IDE right now so this is basically pseudo code:
try (BufferedReader in = new BufferedReader(new FileReader("x.txt"))) {
String line = null;
boolean isOffice = false;
ArrayList<double> officeInts = new ArrayList<double>();
ArrayList<double> addressInts = new ArrayList<double>();
while ((line = in.readLine()) != null) {
if (line.contains("NEW_OFFICE")) {
isOffice = true;
continue;
} else if (line.contains("MAIN_ADDRESS")) {
isOffice = false;
continue;
}
for(String s : line.split(" "){
double num = Double.parseDouble(s);
if(isOffice) {
officeInts.add(num);
} else {
addressInts.add(num);
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
i want to print the output in new line how to do this?
Below is the output.
CHILD: Child line one oneCHILD: Child line one twoCHILD: Child line one three
CHILD: Child line two oneCHILD: Child line two twoCHILD: Child line two three
here is my code for it...
try {
fis = new FileInputStream(file);
fileWriterChild = new FileWriter(outputFileForChild);
brChild = new BufferedWriter(fileWriterChild);
fr = new FileReader(file);
br = new BufferedReader(fr);
int child_line_no = 0;
int buffer = 0;
String currentLine = br.readLine();
while (currentLine != null) {
if (currentLine.contains("CHILD:")) {
Files.write(Paths.get("C:/output.child.txt"),
currentLine.getBytes(), StandardOpenOption.APPEND);
}
currentLine = br.readLine();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
finally {
fis.close();
}
}
Depends on what do you want to do. Here are my two ways:
Appending one line to the end of file
void WriteLog(String date, String message) {
String logFileName = <path to file>;
File logFile = new File(logFileName);
//make directories
logFile.getParentFile().mkdirs();
try (FileWriter writer = new FileWriter(logFile, true)) {
writer.write(message);
writer.write("\r\n");
} catch (IOException ex) {
Cls_log.LogError("Error writing log - " + ex.toString());
}
}
Writing all strings as lines to file (overwriting file)
public static void WriteABcardLog(Map<String,String> etiquetteCache) {
File logFile = new File(<path to file>);
logFile.getParentFile().mkdirs();
try (PrintWriter writer = new PrintWriter(logFile)) {
Iterator<Map.Entry<String, String>> iterator = etiquetteCache.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<String, String> entry = iterator.next();
try {
writer.print(entry.getKey() + ";" + entry.getValue() + "\r\n");
} catch (NullPointerException e) {
Cls_log.LogError(e);
}
}
writer.println();
} catch (IOException ex) {
Cls_log.LogError("Error writing etiquette log - " + ex.toString());
}
}
I'm trying to read in a .csv file containing node data (p-values mostly) into my progam, but in doing so I have to convert them from strings into doubles. Here's the method for it:
public ArrayList<Node> getCSVFile(String file){
String csvFile = file;
BufferedReader br = null;
String line = "";
String cvsSplitBy = ",";
ArrayList<Node> nL = new ArrayList<Node>();
int count = 0;
try {
br = new BufferedReader(new FileReader(csvFile));
while ((line = br.readLine()) != null) {
// use comma as separator
String[] node = line.split(cvsSplitBy);
double pVal = Double.parseDouble(node[4]);
nL.add(new Node(count, node[0], pVal));
count++;
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return nL;
}
The object Node is parameterized as Node(int, String, double), but the first line of the file I'm trying to convert is a column name, and I'm not entirely sure of the nature of the entries after that. Here's a look at the start of the file:
GENE,COMMON,gal1RGexp,gal4RGexp,gal80Rexp,gal1RGsig,gal4RGsig,gal80Rsig
YHR051W,COX6,-0.034,0.111,-0.304,3.75720e-01,1.56240e-02,7.91340e-06
YHR124W,NDT80,-0.090,0.007,-0.348,2.71460e-01,9.64330e-01,3.44760e-01
YKL181W,PRS1,-0.167,-0.233,0.112,6.27120e-03,7.89400e-04,1.44060e-01
YGR072W,UPF3,0.245,-0.471,0.787,4.10450e-04,7.51780e-04,1.37130e-05
YHL020C,OPI1,0.174,-0.015,0.151,1.40160e-04,7.19120e-01,1.53950e-02
YGR145W,YGR145W,0.387,-0.577,-0.088,5.37920e-03,8.27330e-03,7.64180e-01
YGL041C,YGL041C,0.285,-0.086,0.103,4.46050e-04,4.50790e-01,7.03040e-01
YGR218W,CRM1,-0.018,-0.001,-0.018,6.13810e-01,9.79400e-01,8.09690e-01
YOR202W,HIS3,-0.432,-0.710,0.239,1.09790e-02,1.79790e-04,5.48950e-03
YCR005C,CIT2,0.085,0.392,0.464,4.18980e-02,1.53050e-06,2.74360e-06
YER187W,KHS1,0.159,0.139,-0.045,8.51260e-04,4.17830e-03,6.18020e-01
YBR026C,YBR026C,0.276,0.189,0.291,3.63320e-05,6.15230e-04,1.24430e-03
YMR244W,YMR244W,0.078,-0.239,-0.072,5.76050e-01,3.55240e-01,8.85690e-01
Etc etc..
So the code creates nodes for each line based on the first and fifth columns, as well as a unique counter. However how can I skip the first line that just has the column names? I'm a little hesitant to simply have something skipping all first lines in all files, as not all files read may have a string as a first line. Even then, are the following lines suitable for being converted to doubles?
Thanks!
What about skipping lines when parsing the double is not possible?
Like this:
public ArrayList<Node> getCSVFile(String file){
String csvFile = file;
BufferedReader br = null;
String line = "";
String cvsSplitBy = ",";
ArrayList<Node> nL = new ArrayList<Node>();
int count = 0;
try {
br = new BufferedReader(new FileReader(csvFile));
while ((line = br.readLine()) != null) {
// use comma as separator
String[] node = line.split(cvsSplitBy);
double pVal;
try {
pVal = Double.parseDouble(node[4]);
} catch (NumberFormatException e) {
continue; // Skip this line if this isn't a double
}
nL.add(new Node(count, node[0], pVal));
count++;
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return nL;
}
Change the signature of your existing method to:
public ArrayList<Node> getCSVFile(String file, int startAt){
and use startAt inside of your read loop to control how many lines are skipped. I'd recommend creating a default method that returns all lines:
public ArrayList<Node> getCSVFile(String file){
return getCSVFile(file, 0);
}
Alternatively this could be a boolean if you know that you'll either want to skip the first line or none at all.
As for the second part of your question, many of those strings will not be parseable. You may want to read this. But I'm not sure how you expect to parse or use a value like 'YHR051W' (since you said you wanted the first column).
I want to save to a file in android , Some of my arrayList that will be deleted after that.I already have two methods to write/read from android file here but the problem is I want the two methods do that:
the first method must save the element of arraylist then if I call it again it will not write the new element in the same line but write it in another line
The second must read a line (for example I give to the method which line and it returns what the lines contains)
The file looks like that :
firstelem
secondelem
thridelem
anotherelem
another ..
is this possible to do in android java?
PS: I don't need database.
Update
This is My methods :
private void writeToFile(String data) {
try {
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(openFileOutput("config.txt", Context.MODE_PRIVATE));
outputStreamWriter.write(data);
outputStreamWriter.close();
}
catch (IOException e) {
Log.e("Exception", "File write failed: " + e.toString());
}
}
private String readFromFile() {
String ret = "";
try {
InputStream inputStream = openFileInput("config.txt");
if ( inputStream != null ) {
InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
String receiveString = "";
StringBuilder stringBuilder = new StringBuilder();
while ( (receiveString = bufferedReader.readLine()) != null ) {
stringBuilder.append(receiveString);
// stringBuilder.append("\\n");
}
inputStream.close();
ret = stringBuilder.toString();
}
}
catch (FileNotFoundException e) {
Log.e("login activity", "File not found: " + e.toString());
} catch (IOException e) {
Log.e("login activity", "Can not read file: " + e.toString());
}
return ret;
}
Using the save method you linked to you can create the text to save with a StringBuilder:
public String makeArrayListFlatfileString(List<List<String>> listOfLists)
{
StringBuilder sb = new StringBuilder();
if (!listOfLists.isEmpty()) {
// this assumes all lists are the same length
int listLengths = listOfLists.get(0).size();
for (int i=0; i<listLengths; i++)
{
for (List<String> list : listOfLists)
{
sb.append(list.get(i)).append("\n");
}
sb.append("\n"); // blank line after column grouping
}
}
return sb.toString();
}
To parse the contents from that same file (again assuming equal length lists and a String input):
public List<List<String>> getListOfListsFromFlatfile(String data)
{
// split into lines
String[] lines = data.split("\\n");
// first find out how many Lists we'll need
int numberOfLists = 0;
for (String line : lines){
if (line.trim().equals(""))
{
// blank line means new column grouping so stop counting
break;
}
else
{
numberOfLists++;
}
}
// make enough empty lists to hold the info:
List<List<String>> listOfLists = new ArrayList<List<String>>();
for (int i=0; i<numberOfLists; i++)
{
listOfLists.add(new ArrayList<String>());
}
// keep track of which list we should be adding to, and populate the lists
int listTracker = 0;
for (String line : lines)
{
if (line.trim().equals(""))
{
// new block so add next item to the first list again
listTracker = 0;
continue;
}
else
{
listOfLists.get(listTracker).add(line);
listTracker++;
}
}
return listOfLists;
}
For writing, just as Illegal Argument states - append '\n':
void writeToFileWithNewLine(String data) {
try {
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(openFileOutput("config.txt", Context.MODE_PRIVATE));
outputStreamWriter.write(data + "\n");
outputStreamWriter.close();
}
catch (IOException e) { /* handle exception */ }
}
For reading (just the idea, in practice you should read the file only once):
String readLine(final int lineNo) {
InputStream in = new FileInputStream("file.txt");
ArrayList<String> lines = new ArrayList<String>();
try {
InputStreamReader inReader = new InputStreamReader(in);
BufferedReader reader = new BufferedReader(inReader);
String line;
do {
line = reader.readLine();
lines.add(line);
} while(line != null);
} catch (Exception e) { /* handle exceptions */ }
finally {
in.close();
}
if(lineNo < lines.size() && lineNo >= 0) {
return lines.get(lineNo);
} else {
throw new IndexOutOfBoundsException();
}
}
I have written the Java code to read from one file and write to a new file. The file from which I am reading has 5000 lines of records, but when I am writing to a new file I am able to write only between 4700-4900 records.
I think may be I am simultaneously reading from a file and writing to a file, which might be creating a problem.
My code is as follows:
Reading from a file:
public String readFile(){
String fileName = "/home/anand/Desktop/index.txt";
FileReader file = null;
try {
file = new FileReader(fileName);
BufferedReader reader = new BufferedReader(file);
String line = "";
while ((line = reader.readLine()) != null) {
line.replaceAll("ids", "");
System.out.println(line);
returnValue += line + "\n";
}
return returnValue;
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
if (file != null) {
try {
file.close();
} catch (IOException e) {
// Ignore issues during closing
}
}
}
}
Writing to a file:
public void writeFile(String returnValue){
String newreturnValue = returnValue.replaceAll("[^0-9,]", "");
String delimiter = ",";
String newtext ="";
String[] temp;
temp = newreturnValue.split(delimiter);
FileWriter output = null;
try {
output = new FileWriter("/home/anand/Desktop/newinput.txt");
BufferedWriter writer = new BufferedWriter(output);
for(int i =0; i < temp.length ; i++){
writer.write("["+i+"] "+temp[i]);
writer.newLine();
}
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
if (output != null) {
try {
output.close();
} catch (IOException e) {
// Ignore issues during closing
}
}
}
}
I need the suggestion to how to simultaneously read and write to a file.
You need to close writer instead of output. The BufferedWriter may not be writing all of the lines, and won't since you never close it.
You have to close the writer object. The last couple lines probably haven't been flushed onto the text file.
In addition, are you aware of the try-with-resource introduced in Java 7? You can condense your code to this by utilizing it:
public String readFile(){
String fileName = "/home/anand/Desktop/index.txt";
try(BufferedReader reader = new BufferedReader(new FileReader(filename)) {
String line = "";
while ((line = reader.readLine()) != null) {
line.replaceAll("ids", "");
System.out.println(line);
returnValue += line + "\n";
}
return returnValue;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
By doing this, Java will automatically close the reader object for you once the try block completes, regardless of whether or not an exception was thrown. This makes it easier to read your code :)