Search code examples
javaawkruntimeexecbufferedreader

Running AWK from Java to create a file and reading it with BufferedReader


I am trying to create a CSV file from another plain text file which will be sorted, and then I'm trying to read it with a BufferedReader. The question is if it runs simultaneously or if it does the AWK part first and then reads..

The AWK file creation part:

String uniqueSubscribersCommand = "cat " + originalFile +
                " | awk '$1~/^[0-9]*$/ {print $0}' | sort -k 1 | awk '{print $1}' | uniq >> " +
                uniqueFile;
try
{
    Runtime.getRuntime().exec( new String[]{"/bin/sh", "-c", uniqueSubscribersCommand} );
}
catch ( IOException e )
{
     logger.error( "Error during unique subscriber determination" );
}

The reading part, which is right after the creation part:

FileInputStream uniqueFis = new FileInputStream( uniqueFile );
BufferedReader brUnique = new BufferedReader( new InputStreamReader( uniqueFis ) );
while ( ( subscriberId = brUnique.readLine() ) != null )
            {
                // do stuff
            }

I am especially interested in knowing if Java can read the file as it is created if I put the Thread to sleep right after running the AWK command so it would create let's say a 10 second gap between the creation and reading.

Thanks for advice!


Solution

  • Try the following - just a rough idea how this can be done. I haven't actually taken great care to close unclosed streams and such. But make sure you do that. And may be your could read more efficiently using a buffer from a random access file, which I haven't taken care of too. Sorry for that.

    NOTE: The following example is just a SSCCP kind of an example for you test reading a file which can altered from outside and you get the update in the console. If it works, or you think worthy, you can probably improve it according to your use case as you have mentioned, with one thread writing to a file and other read.

            import java.io.IOException;
            import java.io.RandomAccessFile;
            import java.nio.channels.FileChannel;
    
            public class ReadFromFile {
    
                /**
                 * @param args
                 * @throws IOException
                 */
                public static void main(String[] args) throws IOException {
    
                    Runnable runnable = new Runnable() {
    
                        //it's your choice how will you close the channel
                        FileChannel in = null;
    
                        @Override
                        public void run() {
                            long lastChannelPos = 0L;
                            try {
                                /*
                                 *I assume you will run it forever
                                 *if you don't want to run it forever
                                 *put a condition over here in the while loop.
                                */
                                while (true) {
                                    RandomAccessFile raf = new RandomAccessFile(
                                            "your_file_loc", "r");
                                    raf.seek(lastChannelPos);
                                    int c = 0;
                                    StringBuffer sb = new StringBuffer();
                                    while ((c = raf.read()) != -1) {
                                        sb.append((char) c);
                                    }
                                    in = raf.getChannel();
                                    lastChannelPos = in.position();
    
                                    if (!sb.toString().trim().isEmpty()) {
                                        //you can print or use the output as you wish
                                        //for simplicity I'm printing it 
                                        System.out.print(sb.toString().trim());
                                    }
                                    Thread.sleep(1000);
                                    raf.close();
                                }
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                        }
    
                    };
    
                    Thread th = new Thread(runnable);
                    th.start();             
    }
    

    Hope this helps.