Given the following:
import java.io.*;
public class WriteRead {
public void writeToFile(String filename) throws IOException {
FileWriter fw = new FileWriter(filename);
fw.write("testing");
fw.close();
}
public String readFromFile(String filename) throws IOException {
String str = "";
int characterInt = 0;
FileReader fr = new FileReader(filename);
while (characterInt != -1) {
characterInt = fr.read();
str += "" + (char) characterInt;
}
fr.close();
return str;
}
public static void main(String[] args) throws IOException {
WriteRead wR = new WriteRead();
wR.writeToFile("test.java");
System.out.println(wR.readFromFile("test.java"));
}
}
when I run the program it prints the following:
What is the symbol at the end of "testing" and what part of the program causes it to be there?
Use the following code-
while ((characterInt = fr.read()) != -1) {
str += "" + (char) characterInt;
}
since in last iteration when this reads -1 this appends ? in str so please check before adding.and as far as your display of testing0 is concern give me hexcode of this first.
Make the changes as below:
while ((characterInt = fr.read()) != -1) {
//characterInt = fr.read();
str += "" + (char) characterInt;
}
Read the char and compare it with -1 as EOF. You were appending the end of file char in string and then while loop condition was getting failed.
You are setting characterInt = fr.read(); inside your whileloop. You should set this either outside whileloop or in while()condition.
So as per your code, it will run for second iteration also because in second iteration, your characterInt is not equal to -1 (it is holding earlier value i.e. testing).
Related
I have program that has a section that requires me to read and append items to a txt file. I know how to do basic reading and appending but I am confused as to how I would read every 4th line in a txt file and then store it in a variable. Or even every alternate line.
Also, if there are double valued numbers, can I read it as a number and not a string?
To read say every fourth line from a text file you would read a line and update a counter. When the counter reaches 4, you save the line in a String variable. Something like this would do the job:
import java.io.*;
public class SkipLineReader {
public static void main(String[] args) throws IOException {
String line = "";
String savedLine = "";
int counter = 0;
FileInputStream fin = new FileInputStream("text_file.txt");
BufferedReader bufIn = new BufferedReader(new InputStreamReader(fin));
// Save every fourth line
while( (line = bufIn.readLine()) != null) {
counter++;
if( counter == 4 ) {
savedLine = line;
System.out.println(line);
}
}
}
}
To save every alternate line, you would save the line every time the counter reaches two and then reset the counter back to zero. Like this:
// Save every alternate line
while( (line = bufIn.readLine()) != null) {
counter++;
if( counter % 2 == 0 ) {
counter = 0;
savedLine = line;
System.out.println(line);
}
}
As for reading doubles from a file, you could do it with a BufferedReader and then use Double's parseDouble(string) method to retrieve the double value, but a better method is to use the Scanner object in java.util. The constructor for this class will accept a FileInputStream and there is a nextDouble() method that you can use to read a double value.
Here's some code that illustrates using a Scanner object to grab double values from a String (to read from a file, supply a FileInputStream into the Scanner class's constructor):
import java.util.*;
public class ScannerDemo {
public static void main(String[] args) {
String s = "Hello World! 3 + 3.0 = 6 true";
// create a new scanner with the specified String Object
Scanner scanner = new Scanner(s);
// use US locale to be able to identify doubles in the string
scanner.useLocale(Locale.US);
// find the next double token and print it
// loop for the whole scanner
while (scanner.hasNext()) {
// if the next is a double, print found and the double
if (scanner.hasNextDouble()) {
System.out.println("Found :" + scanner.nextDouble());
}
// if a double is not found, print "Not Found" and the token
System.out.println("Not Found :" + scanner.next());
}
// close the scanner
scanner.close();
}
}
This is my code example.
public static void main(String[] args) throws Exception {
// Read file by BufferedReader line by line.
BufferedReader reader;
try {
reader = new BufferedReader(new FileReader("test.txt"));
String line = reader.readLine();
while (line != null) {
line = line.trim();
System.out.println(line);
// Using regular expression to check line is valid number
if (!line.trim().equals("") && line.trim().matches("^\\d+||^\\d+(\\.)\\d+$")) {
double value = Double.valueOf(line.trim());
System.out.println(value);
} else {
String value = line.trim();
System.out.println(value);
}
// Read next line
line = reader.readLine();
}
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
I am using BufferedReader to read a text file line by line. Then i use a method to normalize each line text. But there is something wrong with my normalization method, after the call to it, BufferedReader object stop reading file. Can someone help me with this.
Here is my code:
public static void main(String[] args) {
String string = "";
try (BufferedReader br = new BufferedReader(new FileReader("file.txt"))) {
String line;
while ((line = br.readLine()) != null) {
string += normalize(line);
}
} catch (Exception e) {
}
System.out.println(string);
}
public static String normalize(String string) {
StringBuilder text = new StringBuilder(string.trim());
for(int i = 0; i < text.length(); i++) {
if(text.charAt(i) == ' ') {
removeWhiteSpaces(i + 1, text);
}
}
if(text.charAt(text.length() - 1) != '.') {
text.append('.');
}
text.append("\n");
return text.toString();
}
public static void removeWhiteSpaces(int index, StringBuilder text) {
int j = index;
while(text.charAt(j) == ' ') {
text.deleteCharAt(j);
}
}
and here is the text file that i use:
abc .
asd.
dasd.
I think you have problem in your removeWhiteSpaces(i + 1, text);, and if you have problem in the string process, the reader wont able to read the next line.
You don't check the empty string, and you call text.charAt(text.length()-1), it is a problem too.
Print the exception, change your catch block to write out the exception:
} catch (Exception e) {
e.printStackTrace();
}
The reason is in your while(text.charAt(j) == ' ') {, you don't examine the length of StringBuilder, but you delete it...
Try this:
while ((line = br.readLine()) != null) {
if(line.trim().isEmpty()) {
continue;
}
string += normalize(line);
}
Try ScanReader
Scanner scan = new Scanner(is);
int rowCount = 0;
while (scan.hasNextLine()) {
String temp = scan.nextLine();
if(temp.trim().length()==0){
continue;
}
}
//rest of your logic
The normalize function is causing this.
the following tweak to it shoudl fix this:
public static String normalize(String string) {
if(string.length() < 1) {
return "";
}
StringBuilder text = new StringBuilder(string.trim());
if(text.length() < 1){
return "";
}
for(int i = 0; i < text.length(); i++) {
if(text.charAt(i) == ' ') {
removeWhiteSpaces(i + 1, text);
}
}
if(text.charAt(text.length() - 1) != '.') {
text.append('.');
}
text.append("\n");
return text.toString();
}
The problem is not in your code but in the understanding of the readLine() method. In the documentation is stated:
Reads a line of text. A line is considered to be terminated by any one of a line feed ('\n'), a carriage return ('\r'), or a carriage return followed immediately by a linefeed.
https://docs.oracle.com/javase/7/docs/api/java/io/BufferedReader.html#readLine()
So that means that if the method finds an empty line it will stop reading and return null.
The code proposed by #tijn167 would do the workaround using BufferedReader. If you are not restraint to BufferedReader use ScanReader as #Abhishek Soni suggested.
Also, your method removeWhiteSpaces() is checking for white spaces while the empty lines are not a white space but a carry return \r or a line feed \n or both. So your condition text.charAt(j) == ' ' is never satisfied.
Second line of your file is empty, therefore the while loop stops
class Start
{
File plikIN;
Scanner in;
PrintWriter out;
Start(String input, String output)
{
plikIN = new File(input);
try{
in = new Scanner(plikIN);
out = new PrintWriter(output);
} catch (FileNotFoundException e) {System.out.println("Nie odnaleziono podanego pliku\n"+e);}
}
private void saveing() throws IOException
{
String word;
int wordLength;
String wordTable[];
char c;
while((word = in.next()) != null)
{
wordLength = word.length();
wordTable = new String[wordLength];
for(int k=0; k<wordTable.length; ++k)
{
c = word.charAt(k);
out.println(c);
}
}
out.close();
}
public static void main(String[] args) throws IOException
{
String nazwaPlikuWejsciowego = args[0];
String nazwaPlikuWyjsciowego = args[1];
Start doit = new Start(nazwaPlikuWejsciowego, nazwaPlikuWyjsciowego);
doit.saveing();
}
}
My problem is saving to file. After the saveing method above, the file does not contain any single character. When I move the out.close() to while for instance, the file contains one word. When out.close() is in for, the program saves one character only. Why?
add out.flush() before out.close().
You need to flush the bytes to disk before you close it..
This ((word = in.next()) != null) will throw an exception.
in.next() doesn't return null when there are no more elements. Take a look at the API
I want to develop a program in java wherein the program reads a file using FileInputStream and then separates all the commas(,) and stores the rest of the values in a byte[] array.
for eg.
if my file "a.txt" contains 1,2,3,-21,-44,56,35,11
i want the program to read this file and store the data in a byte array which will contain
byte[] b{1,2,3,-21,-44,56,35,11}.
i have tried to read the file using FileInputStream.read() but after comparing the character for a comma it points to the next character.
can anyone help me out with the code.
import java.io.*;
class a
{
public static void main(String args[])
{
FileInputStream fis;
int inputSize;
try {
fis = new FileInputStream("New.txt");
inputSize = fis.available();
for(int i=0;i<inputSize;i++)
{
if(fis.read()!=44)
System.out.print((char)fis.read());
}
} catch (FileNotFoundException e) {
System.out.println(e.getMessage());
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
}
this might help you out:
private static final String DELIM = ",";
public static void main(String args[]) throws Exception {
// ...
// read the file content line by line with BufferedReader
String line = "5,37,2,-7";
String splitted[] = line.split(DELIM);
byte[] result = new byte[splitted.length];
for (int n = 0; n < splitted.length; ++n) {
result[n] = Byte.parseByte(splitted[n]);
}
System.out.println(Arrays.toString(result));
}
Here's how you can process your file line-by-line:
FileInputStream fis = ...;
BufferedReader br = new BufferedReader(new InputStreamReader(fis));
String line = null;
while ((line = br.readLine()) != null) {
// process the String line
}
if(fis.read()!=44)
System.out.print((char)fis.read());
You call read() twice, so 2 characters will be read and your code prints only the second character. That's why you are wondering about
but after comparing the character for a comma it points to the next
character
That gives the clou:
int readChar;
if((readChar = fis.read()) != 44)
System.out.print((char)readChar);
I have a text file (XML created with XStream) which is 63000 lines (3.5 MB) long. I'm trying to read it using Buffered reader:
BufferedReader br = new BufferedReader(new FileReader(file));
try {
String s = "";
String tempString;
int i = 0;
while ((tempString = br.readLine()) != null) {
s = s.concat(tempString);
// s=s+tempString;
i = i + 1;
if (i % 1000 == 0) {
System.out.println(Integer.toString(i));
}
}
br.close();
Here you can see my attempts to measure reading speed. And it's very low. It takes seconds to read 1000 lines after 10000 line. I'm clearly doing something wrong, but can't understand what. Thanks in advance for your help.
#PaulGrime is right. You are copying the string each time the loop reads a line. Once the string gets big (say 10,000 lines big), it is doing a lot of work to do that copying.
Try this:
StringBuilder sb = new StringBuilder();
while (...reading lines..){
....
sb.append(tempString); //should add newline
...
}
s = sb.toString();
Note: read Paul's answer below on why stripping newlines makes this a bad way to read in a file. Also, as mentioned in the question comments, XStream provides a way to read the file and even if it had not, IOUtils.toString(reader) would be a safer way to read a file.
Some immediate improvements you can do:
Use a StringBuilder instead of concat and +. Using + and concat can really affect the performance, specially when used in loops.
Reduce the access to the disk. You can do it by using a large buffer:
BufferedReader br = new BufferedReader(new FileReader("someFile.txt"), SIZE);
You should use a StringBuilder as String concatenation is extremely slow for even small strings.
Further, try using NIO rather than a BufferedReader.
public static void main(String[] args) throws IOException {
final File file = //some file
try (final FileChannel fileChannel = new RandomAccessFile(file, "r").getChannel()) {
final StringBuilder stringBuilder = new StringBuilder();
final ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
final CharsetDecoder charsetDecoder = Charset.forName("UTF-8").newDecoder();
while (fileChannel.read(byteBuffer) > 0) {
byteBuffer.flip();
stringBuilder.append(charsetDecoder.decode(byteBuffer));
byteBuffer.clear();
}
}
}
You can tune the buffer size if it's still too slow - it's heavily system dependent what buffer size works better. For me it makes very little difference if the buffer is 1K or 4K but on other systems I have know that change to increase speed by an order of magnitude.
In addition to what has already been said, depending on your use of the XML, your code is potentially incorrect as it discards line endings. For example, this code:
package temp.stackoverflow.q15849706;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import com.thoughtworks.xstream.XStream;
public class ReadXmlLines {
public String read1(BufferedReader br) throws IOException {
try {
String s = "";
String tempString;
int i = 0;
while ((tempString = br.readLine()) != null) {
s = s.concat(tempString);
// s=s+tempString;
i = i + 1;
if (i % 1000 == 0) {
System.out.println(Integer.toString(i));
}
}
return s;
} finally {
br.close();
}
}
public static void main(String[] args) throws IOException {
ReadXmlLines r = new ReadXmlLines();
URL url = ReadXmlLines.class.getResource("xml.xml");
String xmlStr = r.read1(new BufferedReader(new InputStreamReader(url
.openStream())));
Object ob = null;
XStream xs = new XStream();
xs.alias("root", Root.class);
// This is incorrectly read/parsed, as the line endings are not
// preserved.
System.out.println("----------1");
System.out.println(xmlStr);
ob = xs.fromXML(xmlStr);
System.out.println(ob);
// This is correctly read/parsed, when passing in the URL directly
ob = xs.fromXML(url);
System.out.println("----------2");
System.out.println(ob);
// This is correctly read/parsed, when passing in the InputStream
// directly
ob = xs.fromXML(url.openStream());
System.out.println("----------3");
System.out.println(ob);
}
public static class Root {
public String script;
public String toString() {
return script;
}
}
}
and this xml.xml file on the classpath (in the same package as the class):
<root>
<script>
<![CDATA[
// taken from http://www.w3schools.com/xml/xml_cdata.asp
function matchwo(a,b)
{
if (a < b && a < 0) then
{
return 1;
}
else
{
return 0;
}
}
]]>
</script>
</root>
produces the following output. The first two lines shows the line endings have been removed, and thus made the Javascript in the CDATA section invalid (as the first JS comment now comments out the whole JS, because the JS lines have been merged).
----------1
<root> <script><![CDATA[// taken from http://www.w3schools.com/xml/xml_cdata.aspfunction matchwo(a,b){if (a < b && a < 0) then { return 1; }else { return 0; }}]]> </script></root>
// taken from http://www.w3schools.com/xml/xml_cdata.aspfunction matchwo(a,b){if (a < b && a < 0) then { return 1; }else { return 0; }}
----------2
// taken from http://www.w3schools.com/xml/xml_cdata.asp
function matchwo(a,b)
{
if (a < b && a < 0) then
{
return 1;
}
else
{
return 0;
}
}
...