java BufferedReader & Writer doesn't work as expected - java

What I was trying to do was to read a mnist train file, and express it's first digit in eleven digits, and keep other same.
So 3,1,4,6 ... to ,0,0,0,1,0,0,0,0,0,0,1,4,6... (there's "" at first digit so total 11 digits)
I thought it's an easy job but it wasn't.
import java.io.*;
public class T {
public static void main(String[] args){
File file = new File("./src/dataset/mnist_train.csv");
File wfile = new File("./src/dataset/conv_mnist_train2.txt");
try{
BufferedReader bufferedReader = new BufferedReader(new FileReader(file));
BufferedWriter fileWriter = new BufferedWriter(new FileWriter(wfile));
String line;
String[] numbers;
int g = 0, cnt = 0, cnt2 = 0;
while ((line = bufferedReader.readLine()) != null) {
cnt2++;
numbers = line.split(",");
for(String i : numbers){
if(g == 0){
for(int j=0; j<10; ++j) {
if(j == Integer.parseInt(i)) fileWriter.write("," + 1);
else{ fileWriter.write("," + 0); cnt++;}
}
g++;
}
else {fileWriter.write("," +i); cnt++;}
}
fileWriter.newLine();
System.out.println(numbers.length + " " + cnt + " " + cnt2);
g = 0; cnt = 0;
}
}catch(Exception e){
e.printStackTrace();
}
}
}
g, cnt, cnt2 are numbers I used for debugging but I didn't find any problem here; it naturally converted each lines with 785 letters into new lines with 795 letters.
import java.io.*;
public class Tes {
public static void main(String[] args){
File file = new File("./src/dataset/conv_mnist_train2.txt");
try{
BufferedReader bufferedReader = new BufferedReader(new FileReader(file));
String line;
int g = 0;
while ((line = bufferedReader.readLine()) != null) {
g++;
String[] N = line.split(",");
if(N.length != 795){
System.out.println(N.length + " " + g);
for(String i : N) System.out.print(i + " ");
System.out.println();
}
}
}catch(Exception e){
e.printStackTrace();
}
}
}
But what happened is that when I run my second code, which shouldn't print anything, printed result and said my 59994th row data is only consisted of 311 letters. But from my first code, I confirmed that my 59994th row has 795 letters. I don't know what's going on here.
Also I tried to use FileWriter and FileReader instead of BufferedWriter & Reader, but it didn't solve problem. Could somebody tell me what's going on, and how to fix this?

The problem was that I didn't close the reader/writer. Didn't know it could end up in serious error.

Related

InputStream reading file and counting lines/words

I'm working on a project and I'm trying to count
1) The number of words.
2) The number of lines in a text file.
My problem is that I can't figure out how to detect when the file goes to the next line so I can increment lines correctly. Basically if next is not a space increment words and if next is a new line, increment lines. How would I do this? Thanks!
public static void readFile(Scanner f) {
int words = 0;
int lines = 0;
while (f.hasNext()) {
if (f.next().equals("\n")) {
lines++;
} else if (!(f.next().equals(" "))) {
words++;
}
}
System.out.println("Total number of words: " + words);
System.out.println("Total number of lines: " + lines);
}
Try this:
public static void readFile(Scanner f) {
int words = 0;
int lines = 0;
while (f.hasNextLine()) {
String line = f.nextLine();
lines++;
for (String token : line.split("\\s+")) {
if (!token.isEmpty()) {
words++;
}
}
}
System.out.println("Total number of words: " + words);
System.out.println("Total number of lines: " + lines);
}
Do you have to use InputStream? (Yes) It is better to use a BufferedReader with an InputStreamReader passed in so you can read the file line by line and increment while doing so.
numLines = 0;
try (BufferedReader br = new BufferedReader(new InputStreamReader(inputStream))) {
String line;
while ((line = br.readLine()) != null)
{
numLines++;
// process the line.
}
}
Then to count the words just split the string using a regular expression that finds whitespaces. myStringArray = MyString.Split(MyRegexPattern); will then return a String[] of all the words. Then all you do is numWords += myStringArray.length();
You can use an InputStreamReader to create a bufferedreader which can read a file line by line:
int amountOfLines = 0;
try {BufferedReader br = new BufferedReader(new InputStreamReader(inputStream))} catch (Exception e) {e.printStackTrace();}
String line;
while ((line = br.readLine()) != null{
numLines++;
// process the line.
}
You can then use the split(String) method to separate every part
Try following:
public static void readFile(Scanner f) {
int words = 0;
int lines = 0;
while (f.hasNextLine()) {
String line = f.nextLine();
String[] arr = line.split("\\s");
words += arr.length;
lines++;
}
System.out.println("Total number of words: " + words);
System.out.println("Total number of lines: " + lines);
}

combine two methods in Java together in this Java code

I want combine the two methods Just some error in my document parser, frequencyCounter and parseFiles thsi code.
I want all of frequencyCounter should be a function that should be executed from within parseFiles, and relevant information don't worry about the file's content should be passed to doSomething so that it knows what to print.
Right now I'm just keep messing up on how to put these two methods together, please give some advices
this is my main class:
public class Yolo {
public static void frodo() throws Exception {
int n; // number of keywords
Scanner sc = new Scanner(System.in);
System.out.println("number of keywords : ");
n = sc.nextInt();
for (int j = 0; j <= n; j++) {
Scanner scan = new Scanner(System.in);
System.out.println("give the testword : ");
String testWord = scan.next();
System.out.println(testWord);
File document = new File("path//to//doc1.txt");
boolean check = true;
try {
FileInputStream fstream = new FileInputStream(document);
BufferedReader br = new BufferedReader(new InputStreamReader(fstream));
String strLine;
strLine = br.readLine();
// Read File Line By Line
int count = 0;
while ((strLine = br.readLine()) != null) {
// check to see whether testWord occurs at least once in the
// line of text
check = strLine.toLowerCase().contains(testWord.toLowerCase());
if (check) {
// get the line
String[] lineWords = strLine.split("\\s+");
// System.out.println(strLine);
count++;
}
}
System.out.println(testWord + "frequency: " + count);
br.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
The code below gives you this output:
Professor frequency: 54
engineering frequency: 188
data frequency: 2
mining frequency: 2
research frequency: 9
Though this is only for doc1, you've to add a loop to iterate on all the 5 documents.
public class yolo {
public static void frodo() throws Exception {
String[] keywords = { "Professor" , "engineering" , "data" , "mining" , "research"};
for(int i=0; i< keywords.length; i++){
String testWord = keywords[i];
File document = new File("path//to//doc1.txt");
boolean check = true;
try {
FileInputStream fstream = new FileInputStream(document);
BufferedReader br = new BufferedReader(new InputStreamReader(fstream));
String strLine;
strLine = br.readLine();
// Read File Line By Line
int count = 0;
while ((strLine = br.readLine()) != null) {
// check to see whether testWord occurs at least once in the
// line of text
check = strLine.toLowerCase().contains(testWord.toLowerCase());
if (check) {
// get the line
String[] lineWords = strLine.split("\\s+");
count++;
}
}
System.out.println(testWord + "frequency: " + count);
br.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
hope this helps!

Why does my summation program throw a NumberFormatException?

I want to read the numbers from the file and sum up the total, but I cannot seem to process the data properly. It is successfully outputting the numbers but is not successfully summing them up.
My code:
import java.io.*;
import java.util.*;
public class Q1 {
public static void main(String[] args) throws IOException {
StringBuffer str = new StringBuffer();
FileWriter output = new FileWriter("number.txt");
Random r = new Random();
for (int i = 1; i < 101; i++) {
str.append(r.nextInt(100) + " ");
}
output.write(str.toString());
System.out.println(str.toString());
output.close();
FileReader reader = new FileReader("number.txt");
BufferedReader input = new BufferedReader(reader);
String line = input.readLine();
int total = 0;
while (line != null) {
System.out.print(line);
total += Integer.parseInt(input.readLine());
}
System.out.println(total);
}
}
And the stacktrace:
Exception in thread "main" java.lang.NumberFormatException: null
at java.lang.Integer.parseInt(Integer.java:542)
at java.lang.Integer.parseInt(Integer.java:615)
at Q1.main(Q1.java:42)
You don't append a ending line char to the output.
Try out this snippet:
StringBuffer str = new StringBuffer();
FileWriter output = new FileWriter("number.txt");
Random r = new Random();
for (int i = 1; i < 101; i++) {
str.append(r.nextInt(100)).append('\n');
}
output.write(str.toString());
System.out.println(str.toString());
output.close();
FileReader reader = new FileReader("number.txt");
BufferedReader input = new BufferedReader(reader);
String line;
int total = 0;
while ((line = input.readLine())!=null) {
total += Integer.parseInt(line);
}
System.out.println(total);
If the output looks weird, examine where the output is being created. That is usually where you will find the problem. Also added in some small changes to give you an idea of a different way you could go about it that might make your life easier.

Java Reading 2D array in from file, numbers separated by comma

This is some code that I found to help with reading in a 2D Array, but the problem I am having is this will only work when reading a list of number structured like:
73
56
30
75
80
ect..
What I want is to be able to read multiple lines that are structured like this:
1,0,1,1,0,1,0,1,0,1
1,0,0,1,0,0,0,1,0,1
1,1,0,1,0,1,0,1,1,1
I just want to essentially import each line as an array, while structuring them like an array in the text file.
Everything I have read says to use scan.usedelimiter(","); but everywhere I try to use it the program throws straight to the catch that replies "Error converting number". If anyone can help I would greatly appreciate it. I also saw some information about using split for the buffered reader, but I don't know which would be better to use/why/how.
String filename = "res/test.txt"; // Finds the file you want to test.
try{
FileReader ConnectionToFile = new FileReader(filename);
BufferedReader read = new BufferedReader(ConnectionToFile);
Scanner scan = new Scanner(read);
int[][] Spaces = new int[10][10];
int counter = 0;
try{
while(scan.hasNext() && counter < 10)
{
for(int i = 0; i < 10; i++)
{
counter = counter + 1;
for(int m = 0; m < 10; m++)
{
Spaces[i][m] = scan.nextInt();
}
}
}
for(int i = 0; i < 10; i++)
{
//Prints out Arrays to the Console, (not needed in final)
System.out.println("Array" + (i + 1) + " is: " + Spaces[i][0] + ", " + Spaces[i][1] + ", " + Spaces[i][2] + ", " + Spaces[i][3] + ", " + Spaces[i][4] + ", " + Spaces[i][5] + ", " + Spaces[i][6]+ ", " + Spaces[i][7]+ ", " + Spaces[i][8]+ ", " + Spaces[i][9]);
}
}
catch(InputMismatchException e)
{
System.out.println("Error converting number");
}
scan.close();
read.close();
}
catch (IOException e)
{
System.out.println("IO-Error open/close of file" + filename);
}
}
I provide my code here.
public static int[][] readArray(String path) throws IOException {
//1,0,1,1,0,1,0,1,0,1
int[][] result = new int[3][10];
BufferedReader reader = new BufferedReader(new FileReader(path));
String line = null;
Scanner scanner = null;
line = reader.readLine();
if(line == null) {
return result;
}
String pattern = createPattern(line);
int lineNumber = 0;
MatchResult temp = null;
while(line != null) {
scanner = new Scanner(line);
scanner.findInLine(pattern);
temp = scanner.match();
int count = temp.groupCount();
for(int i=1;i<=count;i++) {
result[lineNumber][i-1] = Integer.parseInt(temp.group(i));
}
lineNumber++;
scanner.close();
line = reader.readLine();
}
return result;
}
public static String createPattern(String line) {
char[] chars = line.toCharArray();
StringBuilder pattern = new StringBuilder();;
for(char c : chars) {
if(',' == c) {
pattern.append(',');
} else {
pattern.append("(\\d+)");
}
}
return pattern.toString();
}
The following piece of code snippet might be helpful. The basic idea is to read each line and parse out CSV. Please be advised that CSV parsing is generally hard and mostly requires specialized library (such as CSVReader). However, the issue in hand is relatively straightforward.
try {
String line = "";
int rowNumber = 0;
while(scan.hasNextLine()) {
line = scan.nextLine();
String[] elements = line.split(',');
int elementCount = 0;
for(String element : elements) {
int elementValue = Integer.parseInt(element);
spaces[rowNumber][elementCount] = elementValue;
elementCount++;
}
rowNumber++;
}
} // you know what goes afterwards
Since it is a file which is read line by line, read each line using a delimiter ",".
So Here you just create a new scanner object passing each line using delimter ","
Code looks like this, in first for loop
for(int i = 0; i < 10; i++)
{
Scanner newScan=new Scanner(scan.nextLine()).useDelimiter(",");
counter = counter + 1;
for(int m = 0; m < 10; m++)
{
Spaces[i][m] = newScan.nextInt();
}
}
Use the useDelimiter method in Scanner to set the delimiter to "," instead of the default space character.
As per the sample input given, if the next row in a 2D array begins in a new line, instead of using a ",", multiple delimiters have to be specified.
Example:
scan.useDelimiter(",|\\r\\n");
This sets the delimiter to both "," and carriage return + new line characters.
Why use a scanner for a file? You already have a BufferedReader:
FileReader fileReader = new FileReader(filename);
BufferedReader reader = new BufferedReader(fileReader);
Now you can read the file line by line. The tricky bit is you want an array of int
int[][] spaces = new int[10][10];
String line = null;
int row = 0;
while ((line = reader.readLine()) != null)
{
String[] array = line.split(",");
for (int i = 0; i < array.length; i++)
{
spaces[row][i] = Integer.parseInt(array[i]);
}
row++;
}
The other approach is using a Scanner for the individual lines:
while ((line = reader.readLine()) != null)
{
Scanner s = new Scanner(line).useDelimiter(',');
int col = 0;
while (s.hasNextInt())
{
spaces[row][col] = s.nextInt();
col++;
}
row++;
}
The other thing worth noting is that you're using an int[10][10]; this requires you to know the length of the file in advance. A List<int[]> would remove this requirement.

Printing All Values via File Writer

I want to print all the letter that the user will input but the thing is, my program only prints the last value that the user will input, and only the last value is recorded in Ascii.txt. It should look like this
for example : the user input A,B,c,C
I want also to delete the comma but I can't :(
output in "Ascii.txt" should be:
A = 65
B = 66
c = 99
C = 67
please dont laugh at me because im still a student and new to programming, thank you very much
import java.io.*;
public class NewClass2{
public static void main(String args[]) throws IOException{
BufferedReader buff = new BufferedReader(new InputStreamReader(System.in));
System.out.println("Please Enter letters separated by comma: ");
String str = buff.readLine();
for ( int i = 0; i < str.length(); ++i )
{
char c = str.charAt(i);
int j = (int) c;
System.out.println(c +" = " + j);
{
try
{
FileWriter fstream = new FileWriter("Ascii.txt");
BufferedWriter out = new BufferedWriter(fstream);
out.write(c+" = "+j);
out.close();
}catch (Exception e){
}
}
}
}
}
The Problem is that you close and re-open the FileStream for each character you want to dump to your ASCII-File. Thus, your file will be emptied before writing a character. Just move the creation and closing of the stream outside the loop.
BufferedReader buff = new BufferedReader(new InputStreamReader(System.in));
System.out.println("Please Enter letters separated by comma: ");
String str = buff.readLine();
BufferedWriter out = null;
try
{
FileWriter fstream = new FileWriter("Ascii.txt");
out = new BufferedWriter(fstream);
for ( int i = 0; i < str.length(); ++i )
{
char c = str.charAt(i);
int j = c;
System.out.println(c + " = " + j);
out.write(c + " = " + j);
}
}
catch ( Exception e )
{
;
}
finally
{
if ( out != null )
{
out.close();
}
}
In order to remove the commas from the output I would suggest to use String.split():
//...
String[] splittedStr = str.split(",");
for ( int i = 0; i < splittedStr.length; i++ )
{
if ( splittedStr[i].length() > 0 )
{
char c = splittedStr[i].charAt(0);
int j = c;
out.write(c + " = " + j);
}
}
//...
You only write in your file AFTER your loop on str.
BufferedWriter out;
try{
FileWriter fstream = new FileWriter("Ascii.txt");
out = new BufferedWriter(fstream);
for ( int i = 0; i < str.length(); ++i ){
char c = str.charAt(i);
int j = (int) c;
System.out.println(c +" = " + j);
out.write(c+" = "+j);
} catch ...{
...
} finally {
if (out!=null)
out.close();
}
As pointed out, you're closing the stream every time you writes to the file. Maybe you were looking for the flush() method.
Just to complement, if you're using Java 7, you can use the try with resources (so you don't have to bother with closing it):
BufferedReader buff = new BufferedReader(new InputStreamReader(System.in));
System.out.println("Please Enter letters separated by comma: ");
String str = buff.readLine();
try( BufferedWriter out = new BufferedWriter(new FileWriter("Ascii.txt"))){
//Using split
String[] splitted = str.split(",");
for(String s : splitted){
char c = s.charAt(0);
int j = c;
out.write(c + " = " + j);
}
}catch(Exception E){
//You really should catch specific exceptions here.
}

Categories