通过Java中的异步文件通道写入时丢失数据

问题描述:

我正在尝试使用异步文件通道将日期写入文本文件。我用AsynchronousFileChannel制作了程序的3个jar文件,并通过命令提示符同时编译了所有3个jar文件,以读取3个不同的文本文件并输出到一个常见的临时文件中。

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

我的测试文件(3)中有2000条记录要读取,但是公共临时文件中的输出缺少一些记录,该输出应该有6000条记录,但只显示5366或5666或更少。

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.

我无法弄清为什么某些数据会丢失,因为它是异步文件通道的功能。

这是使用异步文件通道的java程序的代码

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 {

     }
}

}
}

这是我的课程,可以从3个文件中读取数据:

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();
          }


使用以下代码部分带有异步文件通道锁定()

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();
        }