Reading in and Writing to files passed as commandline arguments - java

I'm trying to figure out how to pass two files (input.txt and output.txt) as arguments to my main method, read the input file, pass it to a recursive method, then write the mutated string to an output file. I've never worked with commandline arguments before, so I'm not sure how to go about making it work. Here's the code so far:
public static void main(String[] args)
{
ArrayList<String> fileInput = new ArrayList<String>();//ArrayList to hold data from input file
File file = new File(args[0]);
try
{
Scanner scan = new Scanner(new File(args[0]));
FileInputStream readFile = new FileInputStream("input.txt"); // readFile passed from args[0]; args[0] is the argument passed as a string that is held at the 0 index of the args array
fileInput.add(file); //red error line under Add
}
catch(IOException e)
{
e.printStackTrace();
System.exit(0);
}
ArrayList<String> strArray = new ArrayList<String>();
String s;
for(int i = 0; i < file.length() ; i++) //int i = 0; length of stored string data object; i++)
{
//recursiveMarkUp is a string type
strArray.add(file.recursiveMarkUp());//call the markup method and save to an array so we can print to the output file later
//line to print output to output.txt
}
}

When you pass in arguments, they are stored in the args[] array and are accessed like any normal array within main.
File input = new File(args[0]);
File output = new File(args[1]); // make sure you check array bounds
Your comment pointing out the red error line occurs because you are trying to add a File object to an ArrayList<String> which are incompatible. However there's no need to do this step anyway.
You can construct the output stream with the file above:
output.createNewFile(); // create the file so that it exists before writing output
FileOutputStream outStream = new FileOutputStream(output);
OutputStreamWriter outWriter = new OutputStreamWriter(outStream);
If you're using Java 8+, using Files.lines() you can process every line of the file as a stream of Strings
Files.lines(input.toPath())
.map(line -> recursiveMarkup(line))
.forEach(markedUp -> outWriter.write(markedUp));
To do this without streams:
BufferedReader reader = new BufferedReader(new FileReader(input));
String line = "";
while(line != null) {
line = recursiveMarkup(reader.readLine());
outWriter.write(line);
}
I've excluded try/catch blocks for brevity. I've also assumed that you do actually want to process the input file one line at a time; if that's not the case, adjust as necessary. You should also consider explicitly defining file encodings (UTF-8, etc.) when reading/writing data, though here I've also left it out for brevity.

Related

How to piece together String using file reader and char array

Wrote a file in another class and now I'm trying to piece together the file into a JLabel, so I need to convert the name in the file into a string. Using FileReader and a char array to separate each character into an array to be put together in the JLabel.
I'm getting this error on NamePieces[x] = (char)nr;:
Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: 0
at clients.initialize(clients.java:197)
at clients.<init>(clients.java:72)
This is the code that I want to read the file:
try(FileReader nameReader = new FileReader(NamePath)) {
int nr = nameReader.read();
int x = 0;
while(nr != -1) {
namePieces[x] = (char)nr;
nr = nameReader.read();
x++;
}
}
catch (FileNotFoundException e) {}
catch (IOException e1) {}
String name = String.valueOf(namePieces[0]) + namePieces[1];
Doesn't work
Most likely, your problem occurs because namePieces is not initialized. As was already mentioned in the comments, you should not use char[] as a container for your characters (because in real world you won't know the length of the files' contents every time, so you will probably need to resize your container), it is way more better to use StringBuilder, provided by Java standard library. It will protect you from getting out of bounds.
StringBuilder namePieces = new StringBuilder();
File file = new File(filePath);
BufferedReader reader = new BufferedReader(
new InputStreamReader(new FileInputStream(file),
Charset.forName("UTF-8")));
int c;
while((c = reader.read()) != -1) {
namePieces.append((char) c);
}
String nameString = namePieces.toString(); // Use this string as a complete array of needed characters
As you see I changed an approach by using not only StringBuilder, but also BufferedReader. However, for your task you can leave FileReader as it is. Just consider appending characters to builder.
If your file just contains a String there is a straightforward way to read it:
public String readMyFile( String fileName) throws IOException {
Path path = Paths.get(fileName);
return Files.readAllLines(path).get(0);
}

Reading from arguments files to process

I'm having some trouble reading in a file from the command line.
I've never used command line arguments before so I guess I'm a little lost.
Here's what I'm trying so far:
FileInputStream fin1 = null;
for (int i = 0; i < args.length; i++) //command line argument for file input
{
fin1 = new FileInputStream(args[i]);
}
//Scanner scan = new Scanner(fiin1);
I've commented out my scanner because I'm using a different method (into which I'm passing in fin1 as a parameter) and that method has a scanner in it. However, I'm not too sure if I still need the scanner there (maybe to pass into the other method as a param).
Anyway, if I run my code, I get a NullPointerException, which I assume comes from the fact that I initialized my FileInputStream as null. But if I'm changing it in the for loop, why does that matter?
Also, I need to keep my main method the way it is so I can do more in it.
Can anyone help?
Notice that it is called FileInputStream , and so we need to be using a File .
You can simply use a Scanner , and set it to System.in :
Scanner scanner = new Scanner(System.in);
And then afterwards, you can initialize that FileInputStream
How to Read Strings from Scanner in console Application JAVA?
Use following code.
if (args.length < 1) {
System.out.println("No file was given as an argument..!");
System.exit(1);
}
String fileName = args[0];
Scanner scanner = new Scanner(new File(fileName));
if you want to use a FileInputStream then change the last line to create a FileInputStream instance.
fin1 = new FileInputStream(fileName);
No need to use a for-loop if you are giving only one filename as the argument. You can run your code as follow.
javac MyClass.java //Compile your code(Assumed that your file is MyClass.java
java MyClass filename //Change filename with the path to your file
You are getting NullPointerException probably because you are not using filename as a argument when you run your java code.
First of all : when you run your code, you'll reach only the last argument.
You should do like this:
FileInputStream fileInputStream = null;
for (String argument : args) {
fileInputStream = new FileInputStream(argument);
//you should process your argument in block together with creating fis
Scanner scanner = new Scanner(fileInputStream);
//now, when a scanner copy is created, you can use it (or you can use your own
while (scanner.hasNext()) {
System.out.println(scanner.nextLine());
}
}

Parsing a large text file into chunks in Java

I would like to receive some suggestions regarding a little problem I am going to solve in Java.
I have a file consisting in this format:
#
some text
some text
some text
#
some text
some text
some text
#
some text
some text
some text
...and so on.
I would need to read the next chunk of this text file, then to create an InputStream object consting of the read chunk and to pass the InputStream object to a parser. I have to repeat these operations for every chunk in the text file. Each chunk is written between the lines starting with #. The problem is to parse each section between the # tags using a parser which should read each chunk from an InputStream.
The text file could be big, so I would like to obtain good performance.
How could I solve this problem?
I have thought about doing something like this:
FileReader fileReader = new FileReader(file);
BufferedReader bufferedReader = new BufferedReader(fileReader);
Scanner scanner = new Scanner(bufferedReader);
scanner.useDelimiter("#");
List<ParsedChunk> parsedChunks = new ArrayList<ParsedChunk>();
ChunkParser parser = new ChunkParser();
while(scanner.hasNext())
{
String text = scanner.next();
InputStream inputStream = new ByteArrayInputStream(text.getBytes("UTF-8"));
ParsedChunk parsedChunk = parser.parse(inputStream);
parsedChunks.add(parsedChunk);
inputStream.close();
}
scanner.close();
but I am not sure if it would be a good way to do it.
Thank you.
If I have understood correctly. This is what you are trying to achieve. FYI you will need JAVA 7 to get the below code running
public static void main(String[] args) throws IOException {
List<String> allLines = Files.readAllLines(new File("d:/input.txt").toPath(), Charset.defaultCharset());
List<List<String>> chunks = getChunks(allLines);
//Now you have all te chunks and you can process them
}
private static List<List<String>> getChunks(List<String> allLines) {
List<List<String>> result = new ArrayList<List<String>>();
int i = 0;
int fromIndex = 1;
int toIndex = 0;
for(String line : allLines){
i++;
if(line.startsWith("****") && i != 1){ // To skip the first line and the check next delimiter
toIndex = i-1;
result.add(allLines.subList(fromIndex, toIndex));
fromIndex = i;
}
}
return result;
}
didnt quite get the question but u could try using char at this moment as, storing all the character in char array & going thhrough a loop & condiional statement which breaks the string every time it encounters a'#'

How to remove first line of a text file in java [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Replace first line of a text file in Java
Java - Find a line in a file and remove
I am trying to find a way to remove the first line of text in a text file using java. Would like to use a scanner to do it...is there a good way to do it without the need of a tmp file?
Thanks.
If your file is huge, you can use the following method that is performing the remove, in place, without using a temp file or loading all the content into memory.
public static void removeFirstLine(String fileName) throws IOException {
RandomAccessFile raf = new RandomAccessFile(fileName, "rw");
//Initial write position
long writePosition = raf.getFilePointer();
raf.readLine();
// Shift the next lines upwards.
long readPosition = raf.getFilePointer();
byte[] buff = new byte[1024];
int n;
while (-1 != (n = raf.read(buff))) {
raf.seek(writePosition);
raf.write(buff, 0, n);
readPosition += n;
writePosition += n;
raf.seek(readPosition);
}
raf.setLength(writePosition);
raf.close();
}
Note that if your program is terminated while in the middle of the above loop you can end up with duplicated lines or corrupted file.
Scanner fileScanner = new Scanner(myFile);
fileScanner.nextLine();
This will return the first line of text from the file and discard it because you don't store it anywhere.
To overwrite your existing file:
FileWriter fileStream = new FileWriter("my/path/for/file.txt");
BufferedWriter out = new BufferedWriter(fileStream);
while(fileScanner.hasNextLine()) {
String next = fileScanner.nextLine();
if(next.equals("\n"))
out.newLine();
else
out.write(next);
out.newLine();
}
out.close();
Note that you will have to be catching and handling some IOExceptions this way. Also, the if()... else()... statement is necessary in the while() loop to keep any line breaks present in your text file.
Without temp file you must keep everything in main memory. The rest is straight forward: loop over the lines (ignoring the first) and store them in a collection. Then write the lines back to disk:
File path = new File("/path/to/file.txt");
Scanner scanner = new Scanner(path);
ArrayList<String> coll = new ArrayList<String>();
scanner.nextLine();
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
coll.add(line);
}
scanner.close();
FileWriter writer = new FileWriter(path);
for (String line : coll) {
writer.write(line);
}
writer.close();
If file is not too big, you can read is into a byte array, find first new line symbol and write the rest of array into the file starting from position zero. Or you may use memory mapped file to do so.

Capture data read from file into string stream Java

I'm coming from a C++ background, so be kind on my n00bish queries...
I'd like to read data from an input file and store it in a stringstream. I can accomplish this in an easy way in C++ using stringstreams. I'm a bit lost trying to do the same in Java.
Following is a crude code/way I've developed where I'm storing the data read line-by-line in a string array. I need to use a string stream to capture my data into (rather than use a string array).. Any help?
char dataCharArray[] = new char[2];
int marker=0;
String inputLine;
String temp_to_write_data[] = new String[100];
// Now, read from output_x into stringstream
FileInputStream fstream = new FileInputStream("output_" + dataCharArray[0]);
// Convert our input stream to a BufferedReader
BufferedReader in = new BufferedReader (new InputStreamReader(fstream));
// Continue to read lines while there are still some left to read
while ((inputLine = in.readLine()) != null )
{
// Print file line to screen
// System.out.println (inputLine);
temp_to_write_data[marker] = inputLine;
marker++;
}
EDIT:
I think what I really wanted was a StringBuffer.
I need to read data from a file (into a StringBuffer, probably) and write/transfer all the data back to another file.
In Java, first preference should always be given to buying code from the library houses:
http://commons.apache.org/io/api-1.4/org/apache/commons/io/IOUtils.html
http://commons.apache.org/io/api-1.4/org/apache/commons/io/FileUtils.html
In short, what you need is this:
FileUtils.readFileToString(File file)
StringBuffer is one answer, but if you're just writing it to another file, then you can just open an OutputStream and write it directly out to the other file. Holding a whole file in memory is probably not a good idea.
In you simply want to read a file and write another one:
BufferedInputStream in = new BufferedInputStream( new FileInputStream( "in.txt" ) );
BufferedOutputStream out = new BufferedOutputStream( new FileOutputStream( "out.txt" ) );
int b;
while ( (b = in.read()) != -1 ) {
out.write( b );
}
If you want to read a file into a string:
StringWriter out = new StringWriter();
BufferedReader in = new BufferedReader( new FileReader( "in.txt" ) );
int c;
while ( (c = in.read()) != -1 ) {
out.write( c );
}
StringBuffer buf = out.getBuffer();
This can be made more efficient if you read using byte arrays. But I recommend that you use the excellent apache common-io. IOUtils (http://commons.apache.org/io/api-1.4/org/apache/commons/io/IOUtils.html) will do the loop for you.
Also, you should remember to close the streams.
I also come from C++, and I was looking for a class similar to the C++ 'StringStreamReader', but I couldn't find it. In my case (which I think was very simple), I was trying to read a file line by line and then read a String and an Integer from each of these lines. My final solution was to use two objects of the class java.util.Scanner, so that I could use one of them to read the lines of the file directly to a String and use the second one to re-read the content of each line (now in the String) to the variables (a new String and a positive 'int'). Here's my code:
try {
//"path" is a String containing the path of the file we want to read
Scanner sc = new Scanner(new BufferedReader(new FileReader(new File(path))));
while (sc.hasNextLine()) { //while the file isn't over
Scanner scLine = new Scanner(sc.nextLine());
//sc.nextLine() returns the next line of the file into a String
//scLine will now proceed to scan (i.e. analyze) the content of the string
//and identify the string and the positive 'int' (what in C++ would be an 'unsigned int')
String s = scLine.next(); //this returns the string wanted
int x;
if (!scLine.hasNextInt() || (x = scLine.nextInt()) < 0) return false;
//scLine.hasNextInt() analyzes if the following pattern can be interpreted as an int
//scLine.nextInt() reads the int, and then we check if it is positive or not
//AT THIS POINT, WE ALREADY HAVE THE VARIABLES WANTED AND WE CAN DO
//WHATEVER WE WANT WITH THEM
//in my case, I put them into a HashMap called 'hm'
hm.put(s, x);
}
sc.close();
//we finally close the scanner to point out that we won't need it again 'till the next time
} catch (Exception e) {
return false;
}
return true;
Hope that helped.

Categories