Question

I am trying to use asynchronousFileChannel to write the date into a text file. I made 3 jar file of the program with the AsynchronousFileChannel and compiled all 3 jars simultaneously through command prompt to read 3 different text files and output to one common temporary file

I have 2000 records in my test files(3) to be read,but the output in the common temporary file is missing some of the records,the output should have 6000 records but it shows only 5366 or 5666 or sometimes less than that.

I am not able to figure out why some data is lost as it is the functionality of a asynchronousFileChannel.
Here is the code for the java program using asynchronousfilechannel.

        class Writer(){
            public void writeOut(ReadableData fileData)
           throws InterruptedException {
           Path file = null;
          AsynchronousFileChannel asynchFileChannel = null;
          String filePath = tempFileName;
    try {
               file = Paths.get(filePath);
                asynchFileChannel = AsynchronousFileChannel.open(file,
                StandardOpenOption.WRITE, StandardOpenOption.CREATE);

            CompletionHandler<Integer, Object> handler = new CompletionHandler<Integer, Object>() {
             @Override
            public void completed(Integer result, Object attachment) {
                 if (result == Integer.MAX_VALUE) {
                log.debug("Attachment: " + attachment + " " + result
                        + " bytes written");
                log.debug("CompletionHandler Thread ID: "
                        + Thread.currentThread().getId());
                }
                result++;
               }
               @Override
            public void failed(Throwable e, Object attachment) {
                try {
                    throw e;
                } catch (Throwable e1) {
                    e1.printStackTrace();
                }
                log.debug("File Write Failed Exception:");
                e.printStackTrace();
            }
        };

        String printData = fileData.getId() + "|"
                + fileData.getName() + "|" + fileData.getEmpId()
                + "|" + fileData.getServieId() + "|" + "\n";

        asynchFileChannel.write(ByteBuffer.wrap(printData.getBytes()),
                asynchFileChannel.size(), "file write", handler);

        log.debug(printData);
                 }  
      }
    catch (IOException e) {
        e.printStackTrace();
        log.error(e.getMessage());
    } finally {

     }
}

} }

and this is my class to read data from 3 files:

 public class FileReader1 {
static Logger log = Logger.getLogger(FileHandlerNorthBoundMain.class
        .getName());        
        Writer wrO=new Writer();

public static void main(String[] args) throws IOException,
        IllegalFileFormatException, InterruptedException {
        String filePath = "C:\\Users\\Public\\testdata1.csv"; //"C:\\Users\\Public\\testdata2.csv";  "C:\\Users\\Public\\testdata3.csv";
        File file = new File(filePath);
        log.info("Fetching data.... from:  " + filePath);
    ArrayList<ReadableData> list = new ArrayList<ReadableData>();
    FileInputStream fs = null;
    BufferedReader reader = null;
    String Name;
    int Id, EmpId, ServiceId;
    ReadableData readableData = null;
    int count = 0;
    fs = new FileInputStream(file);
    reader = new BufferedReader(new InputStreamReader(fs));
    String line = reader.readLine();
    while (line != null) {
        StringTokenizer st = new StringTokenizer(line, "\\|");
        while (st.hasMoreTokens()) {
            try {
                Id = Integer.parseInt(st.nextToken());
                Name = st.nextToken();
                EmpId = Integer.parseInt(st.nextToken());
                ServiceId = Integer.parseInt(st.nextToken());

                readableData = new ReadableData(Id,
                        , Name, EmpId,ServiceId);
                     wrO.writeOut(readableData);
                list.add(count, readableData);
                count = count++;
            } catch (Exception ex) {
                log.error("Illegal File Format");
                     throw new IllegalFileFormatException("Illegal File Format");
            }
             }
             line = reader.readLine();
            }
         reader.close();
          }
Was it helpful?

Solution

Modify your Writer class with the following code part with asynchronousFileChannel lock()

byte[] test = printData.getBytes();
        Future<FileLock> featureLock = asynchFileChannel.lock();
        log.info("Waiting for the file to be locked ...");
        FileLock lock = featureLock.get();
        if (lock.isValid()) {
            log.debug(printData);
            Future<Integer> featureWrite = asynchFileChannel.write(
                    ByteBuffer.wrap(test), asynchFileChannel.size());
            log.info("Waiting for the bytes to be written ...");
            int written = featureWrite.get();
            log.info("I’ve written " + written + " bytes into "
                    + file.getFileName() + " locked file!");
            lock.release();
        }

OTHER TIPS

This might be because asynchronousFileChannel is thread safe but Bytebuffer is not,care should be taken to ensure that the buffer is not accessed until after the operation has completed.

check the documentation http://openjdk.java.net/projects/nio/javadoc/java/nio/channels/AsynchronousFileChannel.html

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top