首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用java编写asynchronousFileChannel时丢失数据

用java编写asynchronousFileChannel时丢失数据
EN

Stack Overflow用户
提问于 2013-09-16 06:05:12
回答 2查看 1.7K关注 0票数 2

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

我在我的测试文件(3)中有2000条记录要读取,但是普通临时文件中的输出丢失了一些记录,输出应该有6000条记录,但它只显示5366或5666,有时甚至小于该记录。

我无法理解为什么某些数据会丢失,因为它是asynchronousFileChannel的功能。

下面是使用异步文件机制的java程序的代码。

代码语言:javascript
复制
        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个文件中读取数据:

代码语言:javascript
复制
 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();
          }
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-09-17 11:09:17

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

代码语言:javascript
复制
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();
        }
票数 2
EN

Stack Overflow用户

发布于 2013-09-16 06:39:21

这可能是因为asynchronousFileChannel是线程安全的,但Bytebuffer不是,应该注意确保在操作完成后才访问缓冲区。

查看文档http://openjdk.java.net/projects/nio/javadoc/java/nio/channels/AsynchronousFileChannel.html

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18821327

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档