在java中通过asynchronousFileChannel写入时丢失数据

在java中通过asynchronousFileChannel写入时丢失数据,java,asynchronous,channel,data-loss,completionhandler,Java,Asynchronous,Channel,Data Loss,Completionhandler,我正在尝试使用asynchronousFileChannel将日期写入文本文件。我使用AsynchronousFileChannel制作了程序的3个jar文件,并通过命令提示符同时编译了所有3个jar,以读取3个不同的文本文件并输出到一个公共临时文件 我的测试文件(3)中有2000条记录要读取,但是公共临时文件中的输出缺少一些记录,输出应该有6000条记录,但它只显示5366或5666条,有时甚至更少 我无法理解为什么某些数据会丢失,因为这是asynchronousFileChannel的功能。

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

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

我无法理解为什么某些数据会丢失,因为这是asynchronousFileChannel的功能。
下面是使用asynchronousfilechannel的java程序的代码

        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 {

     }
}
类编写器(){
公共无效写出(ReadableData文件数据)
抛出中断异常{
路径文件=null;
AsynchronousFileChannel asynchFileChannel=null;
字符串filePath=tempFileName;
试一试{
file=path.get(filePath);
asynchFileChannel=AsynchronousFileChannel.open(文件,
StandardOpenOption.WRITE、StandardOpenOption.CREATE);
CompletionHandler=新的CompletionHandler(){
@凌驾
已完成公共作废(整数结果、对象附件){
如果(结果==整数.MAX_值){
调试(“附件:“+附件+”+结果
+“写入的字节”);
调试(“CompletionHandler线程ID:”
+Thread.currentThread().getId());
}
结果++;
}
@凌驾
public void失败(可丢弃、对象附件){
试一试{
投掷e;
}捕捉器(可丢弃e1){
e1.printStackTrace();
}
调试(“文件写入失败异常:”);
e、 printStackTrace();
}
};
字符串printData=fileData.getId()+“|”
+fileData.getName()+“|”+fileData.getEmpId()
+“|”+fileData.getServiId()+“|”+“\n”;
asynchFileChannel.write(ByteBuffer.wrap(printData.getBytes()),
asynchFileChannel.size(),“文件写入”,处理程序);
log.debug(printData);
}  
}
捕获(IOE异常){
e、 printStackTrace();
log.error(例如getMessage());
}最后{
}
}
} }

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

 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();
          }
公共类文件读取器1{
静态记录器log=Logger.getLogger(FileHandlerNorthBoundMain.class
.getName());
Writer wrO=新的Writer();
公共静态void main(字符串[]args)引发IOException,
IllegalFileFormatException,InterruptedException{
String filePath=“C:\\Users\\Public\\testdata1.csv”;/“C:\\Users\\Public\\testdata2.csv”;“C:\\Users\\Public\\testdata3.csv”;
文件文件=新文件(文件路径);
log.info(“从:“+filePath”获取数据…);
ArrayList=新建ArrayList();
FileInputStream fs=null;
BufferedReader reader=null;
字符串名;
int-Id、EmpId、ServiceId;
ReadableData ReadableData=null;
整数计数=0;
fs=新文件输入流(文件);
reader=新的BufferedReader(新的InputStreamReader(fs));
字符串行=reader.readLine();
while(行!=null){
StringTokenizer st=新的StringTokenizer(行“\\\\”);
而(st.hasMoreTokens()){
试一试{
Id=Integer.parseInt(st.nextToken());
Name=st.nextToken();
EmpId=Integer.parseInt(st.nextToken());
ServiceId=Integer.parseInt(st.nextToken());
readableData=新的readableData(Id,
,名称,EmpId,ServiceId);
wrO.writeOut(可读数据);
列表.添加(计数,可读数据);
计数=计数++;
}捕获(例外情况除外){
log.error(“非法文件格式”);
抛出新的非法文件格式异常(“非法文件格式”);
}
}
line=reader.readLine();
}
reader.close();
}

这可能是因为asynchronousFileChannel是线程安全的,而Bytebuffer不是,因此应注意确保在操作完成之前不会访问缓冲区


检查文档

使用以下代码部分使用asynchronousFileChannel lock()修改Writer类

byte[]test=printData.getBytes();
Future featureLock=asynchFileChannel.lock();
log.info(“等待文件被锁定…”);
FileLock lock=featureLock.get();
if(lock.isValid()){
log.debug(printData);
Future featureWrite=asynchFileChannel.write(
ByteBuffer.wrap(测试),asynchFileChannel.size();
log.info(“等待写入字节…”);
int writed=featureWrite.get();
log.info(“我已将“+写入+”字节”
+file.getFileName()+“锁定文件!”);
锁定。释放();
}

尝试执行此操作,但输出文件中仍然缺少数据。
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();
        }