Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I have a large text file having thousands of numbers in it that are separated by spaces. I want to read each number using Java FileChannel.
I was able to read the file using the first method mentioned here: http://howtodoinjava.com/2013/05/01/3-ways-to-read-files-using-java-nio/ but i am not sure how i would read each number of two, three and four digits.
My Code:
public static void main(String args[]) {
try
{
String file_name="abc.txt";
RandomAccessFile input_file = new RandomAccessFile(file_name,"r");
FileInputStream in = new FileInputStream(file_name);
FileChannel ch = in.getChannel();
FileChannel inChannel = input_file.getChannel();
long file_size = inChannel.size();
ByteBuffer buffer = ByteBuffer.allocate((int) file_size);
Charset cs = Charset.forName("ASCII");
// inChannel.read(buffer);
int rd;
while ( (rd = ch.read( buffer )) != -1 )
{
buffer.rewind();
System.out.println("String read: ");
CharBuffer chbuf = cs.decode(buffer);
for ( int i = 0; i < chbuf.length(); i++ )
{
System.out.print(chbuf.get());
}
buffer.clear();
inChannel.close();
input_file.close();
}
}
catch (IOException exc){}
}
}
I've modified your code to isolate each number separately (it didn't need much modification):
import java.io.FileInputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.IntBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset;
import java.util.ArrayList;
public class ReadFile {
public static void main(String args[]) {
try
{
String s;
Integer I;
String file_name="C:/Users/User/test.txt";
RandomAccessFile input_file = new RandomAccessFile(file_name,"r");
FileInputStream in = new FileInputStream(file_name);
FileChannel ch = in.getChannel();
FileChannel inChannel = input_file.getChannel();
long file_size = inChannel.size();
ByteBuffer buffer = ByteBuffer.allocate((int) file_size);
Charset cs = Charset.forName("ASCII");
ArrayList<Character> character = new ArrayList<Character>();
// inChannel.read(buffer);
int rd;
while ( (rd = ch.read( buffer )) != -1 )
{
buffer.rewind();
CharBuffer chbuf = cs.decode(buffer);
System.out.println("ASCII values read: ");
System.out.println();
for ( int i = 0; i < chbuf.length(); i++ )
{
int j = chbuf.get();
character.add((char)j);
System.out.println("j("+i+"): "+j+" ");
}
System.out.println();
System.out.println("Chars they represent: ");
System.out.println();
for ( int i = 0; i < character.size(); i++ )
{
System.out.println("character("+i+"): "+character.get(i)+" ");
System.out.println();
s = character.get(i).toString();
if(!(s.equals(" ")||s.equals("\r")))
{
System.out.println("s("+i+"): "+s+" ");
System.out.println();
System.out.println("s("+i+").length(): "+s.length()+" ");
System.out.println();
I = new Integer(s);
System.out.println("I("+i+"): "+I+" ");
System.out.println();
}
}
buffer.clear();
inChannel.close();
input_file.close();
}
}
catch (IOException exc){}
}
}
Related
I have a project where I am to write data (strings and ints) into a binary random access file, and read the data in a separate class. The problem I have is I'm trying to iterate through the file and read the data in a specific order (int, String, String, int), however the Strings are various byte sizes.
I am getting an EOFException but cannot figure out why.
Here is the class which writes the data. Part of the requirements is to limit the number of bytes for the Strings and catch a user defined exception if they are exceeded.
import java.io.RandomAccessFile;
import java.io.IOException;
import java.io.FileNotFoundException;
import java.util.Arrays;
import java.util.ArrayList;
import java.io.File;
public class QuestionBank {
private RandomAccessFile file;
private ArrayList <Questions> listQuestions;
public QuestionBank(){
file = null;
listQuestions = new ArrayList<Questions>();
}
public void storeQuestion (Questions ques) throws IOException {
ques = new Questions(ques.getQuesIDNum(), ques.getQuestion(), ques.getAnswer(), ques.getValue());
listQuestions.add(ques);
byte[] quesBytes = ques.getQuestion().getBytes("UTF-8");
byte[] ansBytes = ques.getAnswer().getBytes("UTF-8");
try {
file = new RandomAccessFile(new File("Question.bin"), "rw");
long fileSize = file.length();
file.seek(fileSize);
file.writeInt(ques.getQuesIDNum());
file.writeUTF(ques.getQuestion());
for (int i = 0; i <= 50 - ques.getQuestion().length(); i++){
file.writeByte(50);
}
if (quesBytes.length > 50) {
throw new ByteSizeException("Question has too many bytes");
}
file.writeUTF(ques.getAnswer());
for (int i = 0; i <= 20 - ques.getAnswer().length(); i++){
file.writeByte(20);
}
if (ansBytes.length > 20) {
throw new ByteSizeException("Answer has too many bytes");
}
file.writeInt(ques.getValue());
file.close();
} catch (IOException e) {
System.out.println("I/O Exception Found");
} catch (ByteSizeException eb) {
System.out.println("String has too many bytes");
}
}
Here is the class which reads the file.
import java.util.ArrayList;
import java.util.Random;
import java.io.RandomAccessFile;
import java.io.IOException;
import java.io.FileNotFoundException;
import java.io.File;
public class TriviaGame {
public static final int RECORD = 78;
private ArrayList<Questions> quesList;
private int IDNum;
private String question;
private String answer;
private int points;
public TriviaGame() {
quesList = new ArrayList<Questions>();
IDNum = 0;
question = "";
answer = "";
points = 0;
}
public void read(){
try {
RandomAccessFile file;
file = new RandomAccessFile(new File("Question.bin"), "r");
long fileSize = file.length();
long numRecords = fileSize/RECORD;
file.seek(0);
for (int i = 0; i < numRecords; i++){
IDNum = file.readInt();
question = file.readUTF();
answer = file.readUTF();
points = file.readInt();
System.out.println("ID: " + IDNum + " Question: " + question + " Answer: " + answer + " Points: " + points);
}
file.close();
} catch (IOException e) {
System.out.println(e.getClass());
System.out.println("I/O Exception found");
}
}
}
Thanks
file.writeUTF(ques.getQuestion());
Here you have written the question.
for (int i = 0; i <= 50 - ques.getQuestion().length(); i++){
file.writeByte(50);
}
if (quesBytes.length > 50) {
throw new ByteSizeException("Question has too many bytes");
}
Here for some unknown reason you are padding the question to 50 bytes. Remove. Same with the answer. You are using readUTF() to read both of these, so all you need is writeUTF() to write them. No padding required.
Or, if you insist on this padding, you have to skip over it when reading: after the first readUTF(), you need to skip over the padding.
I have to prepare a .txt file and count how many times each character of alphabet occurs in the file. I've found a very nice piece of code, but unfortunately, it doesn't work with Polish characters like ą,ę,ć,ó,ż,ź. Even though I put them in the array, for some reason they are not found in the .txt file so the output is 0.
Does anyone know why? Maybe I should count them differently, with "Switch" or something similar.
Before anyone asks - yes, the .txt file is saved with UTF-8 :)
public static void main(String[] args) throws FileNotFoundException {
int ch;
BufferedReader reader;
try {
int counter = 0;
for (char a : "AĄĆĘÓBCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray()) {
reader = new BufferedReader(new FileReader("C:\\Users\\User\\Desktop\\pan.txt"));
char toSearch = a;
counter = 0;
try {
while ((ch = reader.read()) != -1) {
if (a == Character.toUpperCase((char) ch)) {
counter++;
}
}
} catch (IOException e) {
System.out.println("Error");
e.printStackTrace();
}
System.out.println(toSearch + " occurs " + counter);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
Looks like your problem related to encoding and default system charset
try to change reader variable to this
InputStreamReader reader = new InputStreamReader(new FileInputStream("C:\\Users\\User\\Desktop\\pan.txt"), "UTF-8");
try this:
I suggest that you use NIO and this code I have written for you using NIO, RandomAccessFile and MappedByteBuffer that is faster:
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.util.HashMap;
import java.util.Map;
public class FileReadNio
{
public static void main(String[] args) throws IOException
{
Map<Character, Integer> charCountMap = new HashMap<>();
RandomAccessFile rndFile = new RandomAccessFile
("c:\\test123.txt", "r");
FileChannel inChannel = rndFile.getChannel();
MappedByteBuffer buffer = inChannel.map(FileChannel.MapMode.READ_ONLY, 0, inChannel.size());
buffer.load();
for (int i = 0; i < buffer.limit(); i++)
{
char c = (char) buffer.get();
if (charCountMap.get(c) != null) {
int cnt = charCountMap.get(c);
charCountMap.put(c, ++cnt);
}
else
{
charCountMap.put(c, 1);
}
}
for (Map.Entry<Character,Integer> characterIntegerEntry : charCountMap.entrySet()) {
System.out.printf("char: %s :: count=%d", characterIntegerEntry.getKey(), characterIntegerEntry.getValue());
System.out.println();
}
buffer.clear();
inChannel.close();
rndFile.close();
}
}
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
The split method takes two arguments, name of file to split, and size of each split. Could you check if I'm on the write track? And the pseudocode on what to put in the for loop?
import java.io.*;
public class SplitFile {
public static void main(String[] args) throws IOException {
Split("testfile.pdf", 256);
}
public static Split(String filename, int splitSize) throws IOException {
int numberOfFiles = 0;
File file = new File(filename);
numberOfFiles = ((int) file.length() / splitSize) + 1;
for (; numberOfFiles >= 0; numberOfFiles--) {
DataInputStream in = new DataInputStream(new BufferedInputStream(
new FileInputStream(filename)));
DataOutputStream out = new DataOutputStream(
new BufferedOutputStream(new FileOutputStream(file))); //What do I put here?
}
}
}
Required changes
File object per output part, e.g.
Initialize data input stream outside the loop, not inside
Code
File original = new File(filename);
int numberOfFiles = ((int) original.length() / splitSize) + 1;
DataInputStream in =
new DataInputStream(new BufferedInputStream(new FileInputStream(filename)));
// <== just count through parts.
for (int i = 0; i < numberOfFiles; i++) {
File output = new File(String.format("%s-%d", filename, i));
// <== Part of file being output e.g. testfile.pdf-1, testfile.pdf-2
DataOutputStream out = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(output)));
}
For the actual writing...
read bytes from input stream using read() call
write bytes to output stream using write() call
Two approaches, either 1 byte at a time - easiest, but less efficient, or use a buffer, harder to code, but more efficient.
Buffered approach
long length = original.length();
DataInputStream in = new DataInputStream(new BufferedInputStream(new FileInputStream(filename)));
int pos = 0;
byte[] buffer = new byte[splitSize];
for (...) {
...
// make sure you deal with file not being exactly divisible,
// last chunk might be smaller
long remaining = length - pos;
in.read(buffer, pos, (int) Math.min(splitSize, remaining));
out.write(buffer, 0, (int) Math.min(splitSize, remaining));
pos += splitSize;
}
1 byte at a time.
for (...) {
...
for (int i = 0; i < splitSize && pos < length; i++) {
out.write(in.read());
pos++;
}
}
You can do it using the Java NIO API in the following way.
import java.io.IOException;
import java.nio.channels.FileChannel;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
public final class SplitFile {
public static void main(String[] args) throws IOException {
split("testfile.pdf", 256);
}
private static void split(String filename, int splitSize) throws IOException {
int i = filename.lastIndexOf('.');
String basename = filename.substring(0, i);
String ext = filename.substring(i + 1);
Path inputPath = Paths.get(filename);
int numberOfFiles = (int) (Files.size(inputPath) / splitSize) + 1;
try (FileChannel inputChannel = FileChannel.open(inputPath, StandardOpenOption.READ)) {
for (int j = 0; j < numberOfFiles; j++) {
String outputFilename = String.format("%s-%04d.%s", basename, j + 1, ext);
Path outputPath = inputPath.getParent().resolve(outputFilename);
try (FileChannel outputChannel = FileChannel.open(outputPath, StandardOpenOption.CREATE, StandardOpenOption.WRITE)) {
inputChannel.transferTo(j * splitSize, splitSize, outputChannel);
}
}
}
}
}
I need to read text from the user and create an array which contains characters so that I can run them through a FSM. However, I can't seem to get the buffered reader to agree with a non-string type of input. Any advice? I also don't know if I should be using an array or arraylist
static ArrayList<Character> StringList = new ArrayList<Character>();
static char[] data;
public static void main(String[] args){
InputStreamReader ISR = new InputStreamReader (System.in);
BufferedReader BR = new BufferedReader(ISR);
try{
String sCurrentChar;
while((sCurrentChar=BR.readLine())!=null){
for(int i= 0; i<sCurrentChar.length(); i++)
StringList.add(sCurrentChar.charAt(i));
}
for(int i =0; i<StringList.size(); i++){
System.out.println(StringList.get(i));
}
} catch(IOException e){
e.printStackTrace();
}
}
Maybe something like the following could work for you, if you want to read raw byte data, maybe using them later as characters. This might be a better approach than reading input line at a time.
import java.io.DataInputStream;
import java.io.EOFException;
import java.io.IOException;
import java.util.Arrays;
public class a {
public static void main(String[] args){
DataInputStream d = new DataInputStream(System.in);
int[] bytes = new int[256];
try {
int b;
int l = 0;
while((b = d.readByte()) > 0) {
bytes[l++] = b;
if((l % 256) == 0)
bytes = Arrays.copyOf(bytes, (l + 256));
}
} catch(EOFException e) {
// end-of-file
} catch(IOException e) {
System.err.println("AIEEEE: " + e);
System.exit(-1);
}
for(int i = 0; bytes[i] > 0; i++) System.out.print((char)bytes[i]);
System.exit(0);
}
}
The way arrays are treated here is probably a fine example how one should not do it, but then again, this is more about reading bytes/unsigned characters of data than efficiently processing arrays.
I have assignment question I could not get the final answer.
the question was :
Write a program that will write 100 randomly generated
integers to a binary file using the writeInt(int) method in
DataOutputStream. Close the file. Open the file using a
DataInputStream and a BufferedInputStream. Read the integer
values as if the file contained an unspecified number (ignore
the fact that you wrote the file) and report the sum and average
of the numbers.
I believe I done first part of the question which is (write into file), but I don't know how to report the sum.
so far that what I have
import java.io.*;
public class CreateBinaryIO {
public static void main(String [] args)throws IOException {
DataOutputStream output = new DataOutputStream(new FileOutputStream("myData.dat"));
int numOfRec = 0 + (int)(Math.random()* (100 - 0 +1));
int[] counts = new int[100];
for(int i=0;i<=100;i++){
output.writeInt(numOfRec);
counts[i] += numOfRec;
}// Loop i closed
output.close();
}
}
This ReadBinaryIO class:
import java.io.*;
public class ReadBinaryIO {
public static void main(String [] args)throws IOException {
DataInputStream input = new DataInputStream (new BufferedInputStream(new FileInputStream("myData.dat")));
int value = input.readInt();
System.out.println(value + " ");
input.close();
}
}
Try to divide the problem in parts to organice your code, don't forget to flush the OutputStream before you close it.
package javarandomio;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.Random;
public class JavaRandomIO {
public static void main(String[] args) {
writeFile();
readFile();
}
private static void writeFile() {
DataOutputStream output=null;
try {
output = new DataOutputStream(new FileOutputStream("myData.txt"));
Random rn = new Random();
for (int i = 0; i <= 100; i++) {
output.writeInt(rn.nextInt(100));
}
output.flush();
output.close();
} catch (Exception e) {
System.out.println(e.getMessage());
} finally{
try{
output.close();
}catch(Exception e){
System.out.println(e.getMessage());
}
}
}
private static void readFile() {
DataInputStream input=null;
try {
input = new DataInputStream(new FileInputStream("myData.txt"));
int cont = 0;
int number = input.readInt();
while (true) {
System.out.println("cont =" + cont + " number =" + number);
if (input.available() == 4) {
break;
}
number = input.readInt();
cont++;
}
input.close();
} catch (Exception e) {
System.out.println(e.getMessage());
} finally{
try{
input.close();
}catch(Exception e){
System.out.println(e.getMessage());
}
}
}
}
int numOfRec = 0 + (int)(Math.random()* (100 - 0 +1));
That's not generating a random number. Look into java.util.Random.nextInt().
int[] counts = new int[100];
for(int i=0;i<=100;i++){
output.writeInt(numOfRec);
counts[i] += numOfRec;
}// Loop i closed
That wil actually break because you are using i<=100 instead of just i<100 but I'm not sure why you are populating that array to begin with? Also, that code just writes the same number 101 times. The generation of that random number needs to be within the loop so a new one is generated each time.
As far as reading it back, you can loop through your file by using a loop like this:
long total = 0;
while (dataInput.available() > 0) {
total += dataInput.readInt();
}
Try below code where you are trying to read one integer:
DataInputStream input = new DataInputStream (new BufferedInputStream(new FileInputStream("myData.dat")));
int sum = 0;
for(int i =0; i<=100; i++){
int value = input.readInt();
sum += value;
}
System.out.println(value + " ");
input.close();
Or if you want to dynamically set the lenght of the for loop then
create a File object on myData.dat file and then divide the size of file with 32bits
File file = new File("myData.dat");
int length = file.length() / 32;
for(int i =0; i <= length;i++)
So far I submit the assignment and I think I got.
/** Munti ... Sha
course code (1047W13), assignment 5 , question 1 , 25/03/2013,
This file read the integer values as if the file contained an unspecified number (ignore
the fact that you wrote the file) and report the sum and average of the numbers.
*/
import java.io.*;
public class ReadBinaryIO {
public static void main(String [] args)throws ClassNotFoundException, IOException {
//call the file to read
DataInputStream input = new DataInputStream (new BufferedInputStream(new FileInputStream("myData.dat")));
// total to count the numbers, count to count loops process
long total = 0;
int count = 0;
System.out.println("generator 100 numbers are ");
while (input.available() > 0) {
total += input.readInt();
count ++;
System.out.println(input.readInt());
}
//print the sum and the average
System.out.println("The sum is " + total);
System.out.println("The average is " + total/count);
input.close();
}
}
CreateBinaryIO Class:
import java.io.*; import java.util.Random;
public class CreateBinaryIO { //Create a binary file public static
void main(String [] args)throws ClassNotFoundException, IOException {
DataOutputStream output = new DataOutputStream(new
FileOutputStream("myData.dat"));
Random randomno = new Random();
for(int i=0;i<100;i++){ output.writeInt(randomno.nextInt(100)); }// Loop i closed output.close(); } }