/* * cat.java * * Implementation of the CAT command. */ package commands; import java.io.*; import java.text.Collator; import kernel.*; /** * Concatenates files (defined by the arguments) to the standard output, whereas * the argument "-" represents the standard input. If there are no args, it only * transfers the data from standard input to the standard output. * * @author Jan Horký * @version 0.1 - In order to work also with binary files, the concatenation of * the input files uses standard streams instead of the -Reader/-Writer * classes. */ public class cat extends AbstractProcess { /** Size of the buffer used for the binary concatenation. */ private final int BUFFER_SIZE = 1024; /** * Realizes the CAT command. * * @throws AppException * Exception caused by an error in the virtual machines manager. */ public void realization() throws AppException { BufferedReader in = (this.getIn() != null) ? new BufferedReader( new InputStreamReader(this.getIn())) : null; BufferedWriter out = (this.getOut() != null) ? new BufferedWriter( new OutputStreamWriter(this.getOut())) : null; try { if (this.getArgs().size() > 0) { for (String arg : getArgs()) if (arg.equals("-")) processInput(in, out); // Data from stdin, file or pipe else processFile(arg); // Data only from a file } else processInput(in, out); } catch (FileNotFoundException fnfe) { this.printError(fnfe.getMessage() + "\n"); fnfe.printStackTrace(); } catch (IOException ioe) { ioe.printStackTrace(); throw new AppException("I/O operation error\n" + ioe.getMessage(), ioe); } catch (NullPointerException npe) { npe.printStackTrace(); throw new AppException("Input or output wasn't defined\n" + npe.getMessage(), npe); } catch (Exception e) { e.printStackTrace(); throw new AppException("Unexpected error\n" + e.getMessage(), e); } System.out.println("cat"); } private FileInputStream openFile(String fileName) throws FileNotFoundException { File file = new File(fileName); if (!file.isAbsolute()) fileName = System.getProperty("user.dir") + System.getProperty("file.separator") + fileName; return new FileInputStream(fileName); } private void processInput(BufferedReader in, BufferedWriter out) throws IOException { String data; // If we are expecting the data from the standard input ... if (this.getIn() == null) { this.enableStdIn(); in = new BufferedReader(new InputStreamReader(((shell) this.getParent()) .getStdInPipe().getPipeIn())); // Read and process the input data until the next CTRL+D while ((data = in.readLine()) != null) { if (data.length() == 1 && data.charAt(0) == Constants.CTRL_D) break; out.write(data); out.newLine(); out.flush(); } } // Otherwise we are reading from a file or pipe ... else { InputStream input = getIn(); OutputStream output = getOut(); byte[] buffer = new byte[BUFFER_SIZE]; int bytes; while ((bytes = input.read(buffer, 0, BUFFER_SIZE)) > 0 && !isInterrupted()) { output.write(buffer, 0, bytes); output.flush(); } } } private void processFile(String fileName) throws IOException, FileNotFoundException { InputStream input = openFile(fileName); PipedOutputStream output = (PipedOutputStream) ((shell) this.getParent()) .getStdOutPipe().getPipeOut(); byte[] buffer = new byte[BUFFER_SIZE]; int bytes; while ((bytes = input.read(buffer, 0, BUFFER_SIZE)) > 0) { output.write(buffer, 0, bytes); output.flush(); } output.write(13); output.flush(); input.close(); } /** * Provides full description of the command to be used in the MAN command. * * @return Full description of the command including the syntax. */ public String getHelp() { return "\n\nDescription:\nConcatenate FILE(s), or standard input, to standard output.\n\nUsage:\n" + "cat [input1 [input2 [...]]]\n\n" + "input1, input2, ...\tFiles to be concatenated or '-' representing the standard input"; } }