Basically, I need to write a program that takes a user input for multiple text files, and then prints them out into one file.

I usually try not to pose questions here back to back, but alas, I need the help this time round. What really has me baffled is the start of the code I was given to work with. It has many lines that I'm not sure what the actual use is, or how I'm supposed to work with them.

Here is the code:

import java.io.IOException;
import java.io.FileReader;
import java.io.PrintWriter;
import java.util.Scanner;

/**
 * This program concatenates contents of several files into one file.
 */

public class CatFiles
{
   public static void main(String[] args) throws IOException
   {
       Scanner in = new Scanner(System.in);
      
       int j = 0;
       boolean done = false;
       while(!done)
       {
           
           System.out.print("Enter input file: ");
           
           if(in.nextLine().toLowerCase().equals("q"))
           {
               System.out.print("Enter Destination file: ");
               String output = in.next();
               PrintWriter writer = new PrintWriter(output);
               done = true;
           }
           else
           {
               String input = in.next();
               
           }
       }   
       
      if (args.length < 2)
      {
         System.out.println(
               "Usage: CatFiles sourcefile1 sourcefile2 . . . targetfile");
         return;
      }

      String target = args[args.length - 1] ;
      


      for (int i = 0; i < args.length - 1; i++)
      {
         String source = args[i];
     
      }

 

   }
   
}

which lines are confusing you?

if this is starter code, they have given you a lot, but no one can explain the lines you need if the don't know which ones they are.

Some of this code was edited by me, but not much. Only the first if statement. My main problem its the String target line, and the for loop. I don't know what to do with them. I'm also not sure what to do with the input I take in the else.

I'm assuming it should be added to the array some how, and then the array is whats going to be passed to be printed.

Sorry for not being clearer before.

The "starter code" is doing two separate things which seem to be at odds from one another:

import java.io.IOException;
import java.io.FileReader;
import java.io.PrintWriter;
import java.util.Scanner;

/**
 * This program concatenates contents of several files into one file.
 */

public class CatFiles
{
   public static void main(String[] args) throws IOException
   {
       [B]// this section is just reading input files until "q" is entered
      // and then prompting for the output file[/B]
       Scanner in = new Scanner(System.in);
      
       int j = 0;
       boolean done = false;
       while(!done)
       {
           
           System.out.print("Enter input file: ");
           
           if(in.nextLine().toLowerCase().equals("q"))
           {
               System.out.print("Enter Destination file: ");
               String output = in.next();
               PrintWriter writer = new PrintWriter(output);
               done = true;
               [B]// your code here to write the collected input to output[/B]
           }
           else
           {
               String input = in.next();
               [B]// your code to go here to read this file into your collected input[/B]
           }
       }   
       
      [B]// This section is collecting the input and output files
      // from the arguments supplied when the file is run
      // it doesn't really have anything to do with the console
      // stuff above[/B]
      if (args.length < 2)
      {
         System.out.println(
               "Usage: CatFiles sourcefile1 sourcefile2 . . . targetfile");
         return;
      }

      String target = args[args.length - 1] ;
      


      for (int i = 0; i < args.length - 1; i++)
      {
         String source = args[i];
     
      }

 

   }
   
}

If using a StringBuilder, what kind of capacity should I have? I'm thinking I make the builder, then use insert methods to enter the files. Then I would pass the builder to my PrintWriter?

You can declare an initial capacity if you wish, but if you do not then it will manage that itself by expanding the backing arrays as needed.

You just need to add to the StringBuilder with append(String) that you read from your input files.

Pass StringBuilder.toString() to the PrintWriter as needed to write the string.

Also make sure you completely understand the implications of storing the contents of the entire file in a StringBuilder instance since this technique might just result in the entire file contents being loaded in memory which becomes a big issue for huge text files. Consider using a buffer which reads the files in fixed chunks so that you can make a happy compromise between the I/O and memory constraints.

I'm having a problem when running the code. It gives me the initial prompt, but then it doesn't re-prompt after I input a file. Also, I'm not exactly how I should implement a buffer. Could I get a link to the Buffer in the API you're referring to, and perhaps some description on how to implement it?

Here is my code as is, using the append method and toString() methods as suggested.

import java.io.IOException;
import java.io.FileReader;
import java.io.PrintWriter;
import java.util.Scanner;
import java.lang.StringBuilder;

/**
 * This program concatenates contents of several files into one file.
 */

public class CatFiles
{
   public static void main(String[] args) throws IOException
   {
       Scanner in = new Scanner(System.in);
       StringBuilder build = new StringBuilder();
       int j = 0;
       boolean done = false;
       while(!done)
       {
           
           System.out.print("Enter input file: ");
           
           if(in.next().toLowerCase().equals("q"))
           {
               System.out.print("Enter Destination file: ");
               String output = in.next();
               PrintWriter writer = new PrintWriter(output);
               done = true;
               writer.println(build.toString());
           }
           else
           {
               String input = in.next();
               build.append(input);
               
               
           }
       }   
       
      if (args.length < 2)
      {
         System.out.println(
               "Usage: CatFiles sourcefile1 sourcefile2 . . . targetfile");
         return;
      }

      String target = args[args.length - 1] ;
      


      for (int i = 0; i < args.length - 1; i++)
      {
         String source = args[i];
     
      }

 

   }
   
}

Use String input = in.nextLine(); instead of in.next().

Also realize that you are not reading anything from a file, you are appending the filename they entered to your StringBuilder. You have to open that file and read it's contents into your StringBuilder.

s.o.s. makes a good point about managing how much you are accumulating into that StringBuilder in memory before you write it out to your output file. You haven't stated the details of the assignment, but you may want to review the specifics on file size assumptions and io buffering. Those are things that you would have to manage if this were a real application.

So I would use a FileReader to open the file, construct a scanner from the filereader, and append what I take from that scanner?

I'm also unsure of how to proceed with the array testing in the starter code. I'm not sure how to update the array with the correct information, so that the length changes, and the check for length is no longer initiated.

My code at this time:

import java.io.IOException;
import java.io.FileReader;
import java.io.PrintWriter;
import java.util.Scanner;
import java.lang.StringBuilder;

/**
 * This program concatenates contents of several files into one file.
 */

public class CatFiles
{
   public static void main(String[] args) throws IOException
   {
       Scanner in = new Scanner(System.in);
       StringBuilder build = new StringBuilder();

       int j = 0;
       boolean done = false;
   
       while(!done)
       {
           
           System.out.print("Enter input file: ");
           String enter = in.nextLine();
           if(enter.toLowerCase().equals("q"))
           {
               System.out.print("Enter Destination file: ");
               String output = in.next();
               PrintWriter writer = new PrintWriter(output);
               done = true;
               writer.print(build.toString());
           }
           else
           {
               
               
               FileReader reader = new FileReader(enter);
               Scanner console = new Scanner(reader);
               build.append(console.nextLine());
             
              
              
          }
       }   
       
      if (args.length < 2)
      {
         System.out.println(
               "Usage: CatFiles sourcefile1 sourcefile2 . . . targetfile");
         return;
      }

      
      String target = args[args.length - 1] ;
      


      for (int i = 0; i < args.length - 1; i++)
      {
         String source = args[i];
         
     
      }

 

   }

}

I emailed my professor concerning this problem. The method he suggested was to open the file of writing to, then write each file to it line by line. I believe I have a problem somewhere with either my printwriter or my file reader, as I get nothing written to the destination file.

my code:

import java.io.IOException;
import java.io.FileReader;
import java.io.PrintWriter;
import java.util.Scanner;

/**
 * Course Number: Comp 1123.
 * Assignment Number: 
 * Instructor: Rick Giles
 * Question Number: 
 * 
 * @author Thomas Symonds 
 * @version 
 */
public class CatFiles2
{
   public static void main(String[] args) throws IOException
   {
       Scanner in = new Scanner(System.in);
       System.out.print("Enter Target file: ");
       String target = in.next();
       PrintWriter writer = new PrintWriter(target);
       boolean done = false;
       while (!done)
       {
           System.out.print("Enter input file: ");
           String input = in.next();
           FileReader reader = new FileReader(input);
           Scanner console = new Scanner(reader);
           while (console.hasNextLine())
           {
           writer.println(console.nextLine());
           }
           if (input.equals(""));
           done = true;
        }
//       if (args.length < 2)
  //    {
    //     System.out.println(
      //         "Usage: CatFiles sourcefile1 sourcefile2 . . . targetfile");
       //  return;
   //   }
     // String target = args[args.length - 1] ;
      


      for (int i = 0; i < args.length - 1; i++)
      {
         String source = args[i];
      }
    }

}

I solved my problem, partly. I had forgotten to close the writer, closing it gained me a write out. I still only get prompted for one input file however.

This article has been dead for over six months. Start a new discussion instead.