Read a file with InputStream - java

So I have a file that has one line of int : 5551212
I am trying to use InputStream to read this file and then see if I can extract the number written within in it
I did the following steps:
import java.io.*;
class Shuffle {
public static void main(String args[]) throws IOException {
FileInputStream newfile = new FileInputStream("file path");
System.out.println(newfile.getChannel());
System.out.println(newfile.getFD());
System.out.println("Number of remaining bytes:"+newfile.available());
int data;
while ((data = newfile.read()) != -1) {
System.out.print(data + " ");
}
newfile.close();
}
}
However, the output that I got is: 53, 53, 53, 49, 50, 49, 50
I am not really sure what this is suppose to represent, or simply how do I use InputStream on integers

With Java 11 or above, a file can be read using a single line of code - Files.readString
Here is a working example for reading a text file:
// File name: ReadFile.java
import java.nio.file.*;
public class ReadFile {
public static void main(String[] args) throws Exception {
String path = "my-file.txt";
// Read file content as a string
System.out.println(Files.readString(Paths.get(path)));
}
}
Output:
> javac ReadFile.java
> java ReadFile
5551212

The file you're reading is a text file, and thus the bytes you're receiving are representing encoded chars. If you look at ascii table (eg http://www.asciitable.com/) at decimal value 53, you'll see it's corresponding to a char "5"

You are reading an int, and the file is text data, not binary. Hence whatever bytes are in the file are interpreted as binary, and you get these numbers.
To read from a text file, you can either use a Scanner, or read as text first and then convert to int.
import java.io.*;
class Shuffle {
public static void main(String args[]) throws IOException {
try (InputStream file = new FileInputStream("file.txt");
InputStreamReader in = new InputStreamReader(file);
BufferedReader r = new BufferedReader(in)) {
String line = r.readLine();
while (line != null) {
int number = Integer.parseInt(line);
System.out.println(number);
line = r.readLine();
}
}
}
}
This code also uses try-with-resources, which makes sure all readers and files are closed at the end, even if an exception is thrown.

Related

File written in UTF-16 can't be opened, but UTF-8 can

So I'm supposed to insert information in a file with UTF-16 encoding, than do some operations (count lines, words, etc). Problem is that if I choose the UTF-16 encoding, an exception is thrown, but the UTF-8 works fine.
import java.io.*;
import java.util.Scanner;
public final class Q4 {
public static void main(String[ ] args)throws FileNotFoundException{
final String ENCODING = "UTF-16";
final String FILE = " testcount";
PrintWriter out = null;
// Given code – do not modify(!) This will create the UTF-16 test file on your drive.
try {
out = new PrintWriter(FILE, ENCODING);
out.write("Test file for UTF-16\n" + "(contains surrogate pairs:\n" +
"Musical symbols in the range 1D100–1D1FF)\n\n");
out.write("F-clef (1D122): \uD834\uDD22\tCrotchet (1D15F): \uD834\uDD5F\n");
out.write("G-clef (1D120): \uD834\uDD20\tSemiquaver (1D161): \uD834\uDD61\n");
out.write("\n(? lines, ?? words, ??? chars but ??? code points)\n");
} catch (IOException e) { System.out.println("uh? cannot write to file!");
} finally { if (out != null) out.close();
}
// Your code – scan the test file and count lines, words, characters, and code points.
Scanner fin = new Scanner(new File(FILE));
String s = "";
//get the data in file
while (fin.hasNext()){
s = s + fin.next();
System.out.println(s);
}
fin.close();
//count words and lines
}
}
My only guess, a far fetched one, is that it has to something to do with the OS (windows 8.1) not being able to save a UTF- 16 code, but sounds like a silly guess.
Specify the encoding when you read the file:
Scanner fin = new Scanner(new File(FILE), ENCODING);

Reading text files in Java and using data

I am required to evaluate the contents of a .txt file, the file includes 5 numbers, all spaced apart by one (ex: 5555 55 45 47 85) on one line.
The problem isn't reading the file, but actually using each number in the file.
Question: How can I grab the 5 numbers and store each into a unique variable?
Code so far:
import java.io.FileReader;
import java.io.BufferedReader;
public class PassFail {
public static void main(String[] args) {
try{
FileReader file = new FileReader("C:\\new_java\\Final_Project\\src\\student.txt");
BufferedReader reader = new BufferedReader(file);
String line = reader.readLine();
reader.close();
System.out.println(line);
} catch(Exception e) {System.out.println("Error:"+ e);}
}
}
You need to read the file line by line, which you already did. Then you can split the string on space character and iterate over the fields and parse them to Integer
s= reader.readline()
String tokens[]= s.split(" ");
int nums[] = new int[tokens.length];
for(int i=0; i<tokens.lenght; i++) {
nums[i] = Integer.parseInt(tokens[i]);
}
Hope this helps.

Inserting text in middle using RandomAccessFile removes some text after that

My Sample Code
String line = null;
RandomAccessFile file = new RandomAccessFile("D:/mahtew.txt", "rw");
System.out.println(file.getFilePointer());
while((line = file.readLine()) != null){
System.out.println(line);
System.out.println(file.getFilePointer());
if(line.contains("Text to be appended with")){
file.seek(file.getFilePointer());
file.write(" new text has been appended".getBytes());
break;
}
}
file.close();
demo.txt before execution
one two three
Text to be appended with
five six seven
eight nine ten
demo.txt after execution
one two three
Text to be appended with
new text has been appendedten
Also i tried using setLength to change length of file before new text is appended. But still some text is getting trimmed from output file. Any help will be appreciated
Thanks
Mathew
RandomAccessFile
A random access file behaves like a large array of bytes stored in the
file system.
In fact it does not care about shifting the array elements in the case of write operations (only the pointer is advanced). Such an operation overwrites existing values:
Output operations write bytes starting at the file pointer and advance
the file pointer past the bytes written.
When you seek to the file's byte location and writes data, the bytes will be overwritten.
Which is why you get an output like this.
Just imagine editing something in notepad with the insert key pressed. It will replace instead of inserting the new data in between. Same thing's happening here.
EDIT:
You should actually do what Eel is suggesting if you want to edit the file content.
Or you can get the rest of the file and add it to the modified data and write to the file in order to avoid the loss, but that will get ugly and complicated real fast. Not to mention performance penalties.
Understand that when you write with a RAF, you over-write data which was previously held at the file pointer location. If you want to insert text into a file, I suggest that you not use a RAF but rather simply read the text of the file into a String or ArrayList<String> or StringBuilder, using a File held by a FileReader wrapped in a BufferedReader or a File wrapped in a Scanner, alter the Strings or StringBuilder held in memory, and then write the altered data to the new file using a FileWriter wrapped in a PrintWriter.
e.g.,
import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class AppendLine {
private static final String FILE_PATH = "src/tetris/mahtew.txt";
private static final String MARKER_LINE = "Text to be appended with";
private static final String TEXT_TO_ADD = "new text has been appended";
public static void main(String[] args) {
List<String> fileLines = new ArrayList<String>();
Scanner scanner = null;
try {
scanner = new Scanner(new File(FILE_PATH));
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
fileLines.add(line);
if (line.trim().equalsIgnoreCase(MARKER_LINE)) {
fileLines.add(TEXT_TO_ADD);
}
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
if (scanner != null) {
scanner.close();
}
}
PrintWriter pw = null;
try {
pw = new PrintWriter(new File(FILE_PATH));
for (String line : fileLines) {
pw.println(line);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
if (pw != null) {
pw.close();
}
}
}
}
You can use RandomAccessFile in Java to achieve this on one condition:
The size of each line has to be fixed otherwise, when new string is written back, it might override the string in the next line.
Therefore, in my example, I set the line length as 100 and padding with space string when creating the file and writing back to the file.
So in order to allow update, you need to set the length of line a little larger than the longest length of the line in this file.
public class RandomAccessFileUtil {
public static final long RECORD_LENGTH = 100;
public static final String EMPTY_STRING = " ";
public static final String CRLF = "\n";
public static final String PATHNAME = "/home/mjiang/JM/mahtew.txt";
/**
* one two three
Text to be appended with
five six seven
eight nine ten
*
*
* #param args
* #throws IOException
*/
public static void main(String[] args) throws IOException
{
String starPrefix = "Text to be appended with";
String replacedString = "new text has been appended";
RandomAccessFile file = new RandomAccessFile(new File(PATHNAME), "rw");
String line = "";
while((line = file.readLine()) != null)
{
if(line.startsWith(starPrefix))
{
file.seek(file.getFilePointer() - RECORD_LENGTH - 1);
file.writeBytes(replacedString);
}
}
}
public static void createFile() throws IOException
{
RandomAccessFile file = new RandomAccessFile(new File(PATHNAME), "rw");
String line1 = "one two three";
String line2 = "Text to be appended with";
String line3 = "five six seven";
String line4 = "eight nine ten";
file.writeBytes(paddingRight(line1));
file.writeBytes(CRLF);
file.writeBytes(paddingRight(line2));
file.writeBytes(CRLF);
file.writeBytes(paddingRight(line3));
file.writeBytes(CRLF);
file.writeBytes(paddingRight(line4));
file.writeBytes(CRLF);
file.close();
System.out.println(String.format("File is created in [%s]", PATHNAME));
}
public static String paddingRight(String source)
{
StringBuilder result = new StringBuilder(100);
if(source != null)
{
result.append(source);
for (int i = 0; i < RECORD_LENGTH - source.length(); i++)
{
result.append(EMPTY_STRING);
}
}
return result.toString();
}
}
If replaced string is too long, the strings after the line matched with input will be replaced. It seems you have to read file, modify it and write back to old or new file.
Of course, you have options to use multi-threading programming and Java 7's new IO features to improve performance.

NoSuchElementException When writng to file

I am writing a program that read string and integers from file, then copy the data and write to another file. Data entries should be separated by a space.
My input should and output should follow the following format, the first two set of numbers are string while the others are integers:
123123 242323 09 08 06 44
I get Exception in thread "main" java.util.NoSuchElementException when I run my code, I do not know why
import java.util.Scanner;
import java.io.*;
public class Billing {
public static void main(String[] args) throws IOException {
//define the variables
String callingnumber;
String callednumber;
String line;
int startinghour;
int startingminute;
int endinghour;
int endingminute;
//open input and output files
FileReader freader = new FileReader("BillingData.txt");
BufferedReader inFile = new BufferedReader(freader);
FileWriter fwriter = new FileWriter("BillingOutput.txt");
PrintWriter outFile = new PrintWriter (fwriter);
// set space between the numbers
line=inFile.readLine();
while(line!=null)
{
//creat a scanner to use space between the numbers
Scanner space = new Scanner(line).useDelimiter(" ");
callingnumber=space.next();
callednumber=space.next();
startinghour=space.nextInt();
startingminute=space.nextInt();
endinghour=space.nextInt();
endingminute=space.nextInt();
// writing data to file
outFile.printf("%s %s %d %d %d %d", callingnumber, callednumber,startinghour, startingminute, endinghour, endingminute);
line=inFile.readLine();
}//end while
//close the files
inFile.close();
outFile.close();
}//end of mine
}//end of class
I suspect that the scanner has run out of data in the line - probably because there are less than 6 values in it. To avoid the error you should do something like this:
if (space.hasNextInt()) {
startingHour = space.nextInt();
}
Your Scanner is trying to read in a token that either doesn't exist or is of the wrong type. Myself, I'd split the String, line using " " as my delimiter and then deal with the array returned.

Java: How to read a text file

I want to read a text file containing space separated values. Values are integers.
How can I read it and put it in an array list?
Here is an example of contents of the text file:
1 62 4 55 5 6 77
I want to have it in an arraylist as [1, 62, 4, 55, 5, 6, 77]. How can I do it in Java?
You can use Files#readAllLines() to get all lines of a text file into a List<String>.
for (String line : Files.readAllLines(Paths.get("/path/to/file.txt"))) {
// ...
}
Tutorial: Basic I/O > File I/O > Reading, Writing and Creating text files
You can use String#split() to split a String in parts based on a regular expression.
for (String part : line.split("\\s+")) {
// ...
}
Tutorial: Numbers and Strings > Strings > Manipulating Characters in a String
You can use Integer#valueOf() to convert a String into an Integer.
Integer i = Integer.valueOf(part);
Tutorial: Numbers and Strings > Strings > Converting between Numbers and Strings
You can use List#add() to add an element to a List.
numbers.add(i);
Tutorial: Interfaces > The List Interface
So, in a nutshell (assuming that the file doesn't have empty lines nor trailing/leading whitespace).
List<Integer> numbers = new ArrayList<>();
for (String line : Files.readAllLines(Paths.get("/path/to/file.txt"))) {
for (String part : line.split("\\s+")) {
Integer i = Integer.valueOf(part);
numbers.add(i);
}
}
If you happen to be at Java 8 already, then you can even use Stream API for this, starting with Files#lines().
List<Integer> numbers = Files.lines(Paths.get("/path/to/test.txt"))
.map(line -> line.split("\\s+")).flatMap(Arrays::stream)
.map(Integer::valueOf)
.collect(Collectors.toList());
Tutorial: Processing data with Java 8 streams
Java 1.5 introduced the Scanner class for handling input from file and streams.
It is used for getting integers from a file and would look something like this:
List<Integer> integers = new ArrayList<Integer>();
Scanner fileScanner = new Scanner(new File("c:\\file.txt"));
while (fileScanner.hasNextInt()){
integers.add(fileScanner.nextInt());
}
Check the API though. There are many more options for dealing with different types of input sources, differing delimiters, and differing data types.
This example code shows you how to read file in Java.
import java.io.*;
/**
* This example code shows you how to read file in Java
*
* IN MY CASE RAILWAY IS MY TEXT FILE WHICH I WANT TO DISPLAY YOU CHANGE WITH YOUR OWN
*/
public class ReadFileExample
{
public static void main(String[] args)
{
System.out.println("Reading File from Java code");
//Name of the file
String fileName="RAILWAY.txt";
try{
//Create object of FileReader
FileReader inputFile = new FileReader(fileName);
//Instantiate the BufferedReader Class
BufferedReader bufferReader = new BufferedReader(inputFile);
//Variable to hold the one line data
String line;
// Read file line by line and print on the console
while ((line = bufferReader.readLine()) != null) {
System.out.println(line);
}
//Close the buffer reader
bufferReader.close();
}catch(Exception e){
System.out.println("Error while reading file line by line:" + e.getMessage());
}
}
}
Look at this example, and try to do your own:
import java.io.*;
public class ReadFile {
public static void main(String[] args){
String string = "";
String file = "textFile.txt";
// Reading
try{
InputStream ips = new FileInputStream(file);
InputStreamReader ipsr = new InputStreamReader(ips);
BufferedReader br = new BufferedReader(ipsr);
String line;
while ((line = br.readLine()) != null){
System.out.println(line);
string += line + "\n";
}
br.close();
}
catch (Exception e){
System.out.println(e.toString());
}
// Writing
try {
FileWriter fw = new FileWriter (file);
BufferedWriter bw = new BufferedWriter (fw);
PrintWriter fileOut = new PrintWriter (bw);
fileOut.println (string+"\n test of read and write !!");
fileOut.close();
System.out.println("the file " + file + " is created!");
}
catch (Exception e){
System.out.println(e.toString());
}
}
}
Just for fun, here's what I'd probably do in a real project, where I'm already using all my favourite libraries (in this case Guava, formerly known as Google Collections).
String text = Files.toString(new File("textfile.txt"), Charsets.UTF_8);
List<Integer> list = Lists.newArrayList();
for (String s : text.split("\\s")) {
list.add(Integer.valueOf(s));
}
Benefit: Not much own code to maintain (contrast with e.g. this). Edit: Although it is worth noting that in this case tschaible's Scanner solution doesn't have any more code!
Drawback: you obviously may not want to add new library dependencies just for this. (Then again, you'd be silly not to make use of Guava in your projects. ;-)
Use Apache Commons (IO and Lang) for simple/common things like this.
Imports:
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.ArrayUtils;
Code:
String contents = FileUtils.readFileToString(new File("path/to/your/file.txt"));
String[] array = ArrayUtils.toArray(contents.split(" "));
Done.
Using Java 7 to read files with NIO.2
Import these packages:
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
This is the process to read a file:
Path file = Paths.get("C:\\Java\\file.txt");
if(Files.exists(file) && Files.isReadable(file)) {
try {
// File reader
BufferedReader reader = Files.newBufferedReader(file, Charset.defaultCharset());
String line;
// read each line
while((line = reader.readLine()) != null) {
System.out.println(line);
// tokenize each number
StringTokenizer tokenizer = new StringTokenizer(line, " ");
while (tokenizer.hasMoreElements()) {
// parse each integer in file
int element = Integer.parseInt(tokenizer.nextToken());
}
}
reader.close();
} catch (Exception e) {
e.printStackTrace();
}
}
To read all lines of a file at once:
Path file = Paths.get("C:\\Java\\file.txt");
List<String> lines = Files.readAllLines(file, StandardCharsets.UTF_8);
All the answers so far given involve reading the file line by line, taking the line in as a String, and then processing the String.
There is no question that this is the easiest approach to understand, and if the file is fairly short (say, tens of thousands of lines), it'll also be acceptable in terms of efficiency. But if the file is long, it's a very inefficient way to do it, for two reasons:
Every character gets processed twice, once in constructing the String, and once in processing it.
The garbage collector will not be your friend if there are lots of lines in the file. You're constructing a new String for each line, and then throwing it away when you move to the next line. The garbage collector will eventually have to dispose of all these String objects that you don't want any more. Someone's got to clean up after you.
If you care about speed, you are much better off reading a block of data and then processing it byte by byte rather than line by line. Every time you come to the end of a number, you add it to the List you're building.
It will come out something like this:
private List<Integer> readIntegers(File file) throws IOException {
List<Integer> result = new ArrayList<>();
RandomAccessFile raf = new RandomAccessFile(file, "r");
byte buf[] = new byte[16 * 1024];
final FileChannel ch = raf.getChannel();
int fileLength = (int) ch.size();
final MappedByteBuffer mb = ch.map(FileChannel.MapMode.READ_ONLY, 0,
fileLength);
int acc = 0;
while (mb.hasRemaining()) {
int len = Math.min(mb.remaining(), buf.length);
mb.get(buf, 0, len);
for (int i = 0; i < len; i++)
if ((buf[i] >= 48) && (buf[i] <= 57))
acc = acc * 10 + buf[i] - 48;
else {
result.add(acc);
acc = 0;
}
}
ch.close();
raf.close();
return result;
}
The code above assumes that this is ASCII (though it could be easily tweaked for other encodings), and that anything that isn't a digit (in particular, a space or a newline) represents a boundary between digits. It also assumes that the file ends with a non-digit (in practice, that the last line ends with a newline), though, again, it could be tweaked to deal with the case where it doesn't.
It's much, much faster than any of the String-based approaches also given as answers to this question. There is a detailed investigation of a very similar issue in this question. You'll see there that there's the possibility of improving it still further if you want to go down the multi-threaded line.
read the file and then do whatever you want
java8
Files.lines(Paths.get("c://lines.txt")).collect(Collectors.toList());

Categories