ICode9

精准搜索请尝试: 精确搜索
首页 > 系统相关> 文章详细

java-如何在多进程,多线程环境中读取文件

2019-10-30 20:00:33  阅读:94  来源: 互联网

标签:multithreading file-io multiprocessing java


我在使用文件锁定的多进程环境时成功读取文件
在使用多线程(单进程)的情况下,我使用一个队列填充了文件名,分别打开了一个线程,从中读取,然后等到整个读取结束后,再用它们重命名.这样,我曾经以多线程(批量)读取文件.

现在,我想同时使用多进程和多线程读取目录中的文件.我尝试合并两种方法,但效果不佳.日志显示很多文件都显示FileNotFound异常(因为它们的名称已更改),某些文件从未读取(因为线程死亡),有时未释放锁.

 ///////////////////////////////////////////////////////////////////////
     //file filter inner class
     class myfilter implements FileFilter{

            @Override
            public boolean accept(File pathname) {
                // TODO Auto-generated method stub
                Pattern pat = Pattern.compile("email[0-9]+$");
                Matcher mat = pat.matcher(pathname.toString());
                if(mat.find()) {
                    return true;
                }
                return false;
            }

        }
     /////////////////////////////////////////////////////////////////////////


    myfilter filter = new myfilter();
    File alreadyread[] = new File[5];
    Thread t[] = new Thread[5];
    fileread filer[] = new fileread[5];
    File file[] = directory.listFiles(filter);
    FileChannel filechannel[] = new FileChannel[5];
    FileLock lock[] = new FileLock[5];
    tuple_json = new ArrayList();
    //System.out.println("ayush");
    while(true) {
        //declare a queue
        ConcurrentLinkedQueue filequeue = new ConcurrentLinkedQueue();

        //addfilenames to queue and their renamed file names
        try{
        if(file.length!=0) {
            //System.out.println(file.length);
            for(int i=0;i<5 && i<file.length;i++) {

                System.out.println("acquiring lock on file " + file[i].toString());
                try{
                filechannel[i] = new RandomAccessFile(file[i], "rw").getChannel();
                lock[i] = filechannel[i].tryLock();
                }
                catch(Exception e) {
                    file[i] = null;
                    lock[i] = null;
                    System.out.println("cannot acquire lock");
                }
                if(lock[i]!=null){
                    System.out.println("lock acquired on file " + file[i].toString());
                   filequeue.add(file[i]);
                   alreadyread[i] = new File(file[i].toString() + "read");
                   System.out.println(file[i].toString() + "-----" + times);
                }
                else{

                   System.out.println("else condition of acquiring lock");
                    file[i] = null;
                }
                System.out.println("-----------------------------------");
            }

        //starting the thread to read the files
        for(int i=0;i<5 && i<file.length && lock[i]!=null && file[i]!=null;i++){
            filer[i] = new fileread(filequeue.toArray()[i].toString());
            t[i] = new Thread(filer[i]);
            System.out.println("starting a thread to read file" + file[i].toString());
            t[i].start();
        }

        //read the text
        for(int i=0;i<5 && i<file.length && lock[i]!=null && file[i]!=null;i++) {
            try {
                System.out.println("waiting to read " + file[i].toString() + " to be read completely");
                t[i].join();
                System.out.println(file[i] + " was read completetly");
                //System.out.println(filer[i].getText());

            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

        }
        //file has been read Now rename the file
        for(int i=0;i<5 && i<file.length && lock[i]!=null && file[i]!=null;i++){
            if(lock[i]!=null){
                System.out.println("renaming file " + file[i].toString());
                file[i].renameTo(alreadyread[i]);
                System.out.println("releasing lock on file  " + file[i].toString());
                lock[i].release();
        }
        }

//rest of the processing
/////////////////////////////////////////////////////////////////////////////////////////////////////

文件读取类

class fileread implements Runnable{
//String loc = "/home/ayusun/workspace/Eclipse/fileread/bin";
String fileloc;
BufferedReader br;
String text = "";
public fileread(String filename) {
    this.fileloc = filename;
}
@Override
public void run() {
    try {
        br = new BufferedReader(new FileReader(fileloc));
        System.out.println("started reading file" + fileloc);
        String currline;
        while((( currline = br.readLine())!=null)){
            if(text == "")
                text += currline;
            else
                text += "\n" + currline;
        }

        System.out.println("Read"  + fileloc  + " completely");
        br.close();

    } catch ( IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

}

public String getText() {
    return text;
}
}

我想知道,是否还有其他方法可以采用.

解决方法:

如果要创建对文件的独占访问,则不能使用文件锁定,因为在大多数操作系统上,文件锁定是建议性的,而非强制性的.

我建议为所有进程创建一个通用的锁目录.在此锁定目录中,您将在打开文件之前为每个要锁定的文件创建一个目录.

与文件创建不同,最大的优点是目录创建是原子的.这样,您可以使用Files.createDirectory()(如果仍然使用Java6,但也可以使用File的.mkdir(),但不要忘记检查返回码)来锁定读取的文件.如果失败,则表明其他人正在使用该文件.

当然,使用完文件后,请不要忘记删除与此文件匹配的锁目录…(在finally块中)

(注意:在Java 7中,您可以使用Files.newBufferedReader();甚至还有Files.readAllLines())

标签:multithreading,file-io,multiprocessing,java
来源: https://codeday.me/bug/20191030/1970430.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有