1

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

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

我无法弄清楚为什么某些数据会丢失,因为它是 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 {

     }
}

} }

这是我从 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();
          }
4

2 回答 2

1

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

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

于 2013-09-16T06:39:21.657 回答
1

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

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();
        }
于 2013-09-17T11:09:17.923 回答