精华内容
下载资源
问答
  • java多线程读写文件之文件锁
    2021-02-12 16:53:49

    文件修改始终是一件很麻烦也很出错的行为。多线程读写文件更是会加大文件内容混乱的概率,这时,必定要保证在某一个时刻,只有一个线程在对文件进行读写操做。那么其余访问文件的线程该怎么办呢?就像去ATM取钱同样,当ATM正在被使用时,那么其余想要使用ATM的人只能等待知道ATM能使用。java

    读写文件也同样,当一个线程得到文件时,给予这个线程文件锁。只有拥有文件锁的线程才能操做文件,其余线程就须要一直等待,直到得到文件锁。多线程

    下面的代码实现了以下的功能:app

    读取文件内容;

    对内容进行修改;

    将修改后的内容写入文件;

    替换掉原有的内容。

    须要注意的地方有:dom

    文件锁定;

    替换文件内容时文件指针的位置;

    新内容写入文件时,会覆盖掉原有的内容。注意是覆盖。过新的内容比原有内容少,那么只会覆盖掉新内容长度的字符。例如原有内容是:ab,新写入的内容是:1,些动做完成只够,文件的内容是:1b。所以这里要注意选择。

    private void addConfig(String configStr){

    File file = new File(CONFIG_FILE);

    RandomAccessFile write = null;

    FileChannel channel = null;

    FileLock lock = null;

    try {

    write = new RandomAccessFile(file, "rws");

    channel = write.getChannel();

    while(true){

    try {

    lock = channel.lock();//尝试得到文件锁,若文件正在被使用,则一直等待

    break;

    } catch (Exception e) {

    System.out.println("write::: some other thread is holding the file...");

    }

    }

    String content = readConfig(write, configStr);

    write.seek(0);//替换原有文件内容

    write.write(content.getBytes());

    lock.release();

    channel.close();

    write.close();

    } catch (IOException e) {

    throw new FileNotExistException("config file is not exist").addScene("config", CONFIG_FILE);

    }

    }

    代码中的

    readConfig(RandomAccessFile write , String configStr)方法会读取文件内容,并将字符串

    configStr插入其中。其实现以下:

    private String readConfig(RandomAccessFile reader, String configStr) {

    StringBuffer sb = new StringBuffer();

    try {

    if (reader != null) {

    String txt = new String();

    while ((txt = reader.readLine()) != null) {

    sb.append(txt + "\n");

    if (" \"collect_items\":[".equals(txt)) {

    sb.append(configStr);

    }

    }

    } else {

    throw new FileIOException("reader is null...").addScene(

    "reader", reader);

    }

    return sb.toString();

    } catch (IOException e) {

    throw new FileIOException("exception when read content").addScene(

    "config", CONFIG_FILE);

    }

    }

    由于读写都是用的同一个

    RandomAccessFile,因此当读取动做执行完成以后,此时的文件指针已经在文件内容末尾了。要替换掉原有的内容就须要将指针移到文件首部。须要

    write.seek(0);这个方法来实现。此时写入的内容就会覆盖掉原来文件中的内容。

    不足:

    在获取文件锁的地方:

    while(true){

    try {

    lock = channel.lock();

    break;

    } catch (Exception e) {

    System.out.println("write::: some other thread is holding the file...");

    }

    }

    不论怎么看都以为有点别扭,你是否有好的解决方案呢?

    更多相关内容
  • 主要介绍了java多线程读写文件示例,需要的朋友可以参考下
  • java多线程读取文件

    2015-07-08 23:09:57
    Java多线程读大文件 java多线程文件:多线程往队列中写入数据
  • 主要为大家详细介绍了java多线程读取多个文件的方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
  • Java多线程读取文件

    2020-12-22 21:24:55
    前言  是五一假期第,按理应该是快乐玩耍的日子,...  为了充分利用多线程读取,需要把文件划分成多个区域,供每个线程读取。那么需要有一个算法来计算出每个线程读取的开始位置和结束位置。那么首先根据配置的线程
  • Java多线程读取文件

    2021-08-16 18:48:52
    import java.io.*; /** * @ClassName: ReadFile * @Description: java类作用描述 * @Author: qiaowenxuan * @CreateDate: 2021/8/16$ 18:36$ * @Version: 1.0 */ public class ReadFile { public static ...

    多线程读取单文件

    package com.qwx.test;
    
    import java.io.*;
    
    /**
     * @ClassName: ReadFile
     * @Description: java类作用描述
     * @Author: qiaowenxuan
     * @CreateDate: 2021/8/16$ 18:36$
     * @Version: 1.0
     */
    public class ReadFile {
        public static void main(String[] args) {
            File file = new File("F://xaa.txt");
            ReaderThread thread1 = new ReaderThread(file);
            ReaderThread thread2 = new ReaderThread(file);
    
            new Thread(thread1,"thread1").start();
            new Thread(thread2,"thread2").start();
        }
    }
    
    class Reader {
        public static void read(File file) throws IOException {
            FileInputStream fileInputStream = new FileInputStream(file);
            InputStreamReader reader = new InputStreamReader(fileInputStream);
            BufferedReader bufferedReader = new BufferedReader(reader);
            String line = null;
            while (null != (line = bufferedReader.readLine())) {
                System.out.println(line);
            }
            bufferedReader.close();
        }
    }
    
    class ReaderThread implements Runnable {
    
        private File file;
        public ReaderThread(File file) {
            this.file = file;
        }
    
        @Override
        public void run() {
            try {
                Reader.read(file);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    
    

    多线程读取文件列表

    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.data.redis.core.RedisTemplate;
    import redis.clients.jedis.Jedis;
    
    import java.io.*;
    import java.util.ArrayList;
    import java.util.List;
    import java.util.concurrent.TimeUnit;
    
    public class FavFileUtil {
        public static List getFileList(String filePath) {
            List fileList = new ArrayList();
            File file = new File(filePath);
            if (!file.isDirectory()) {
                System.out.println("文件【" + file.getName() + "】:" + file.getAbsolutePath());
                fileList.add(file);
            } else {
                System.out.println("文件夹【" + file.getName() + "】:" + file.getAbsolutePath());
                File[] files = file.listFiles();
                for (int i = 0; i < files.length; i++) {
                    if (!files[i].isDirectory()) {
                        System.out.println("  文件【" + files[i].getName() + "】:");
                        fileList.add(files[i]);
                    } else if (files[i].isDirectory()) {
                        getFileList(files[i].getAbsolutePath());
                    }
                }
            }
            return fileList;
        }
    
        public static List subFiles(List list, int startIndex, int endIndex) {
            if (endIndex > list.size()) {
                return list.subList(startIndex, list.size());
            }
            return list.subList(startIndex, endIndex);
        }
    
        static int i = 0;
        public static void readFile(File file) throws IOException {
            Jedis jedis = new Jedis("127.0.0.1", 6379);
            //读取文件
            FileInputStream is = new FileInputStream(file);
    
            //获取文件的字符流
            InputStreamReader isr = new InputStreamReader(is);
    
            //缓冲
            BufferedReader br = new BufferedReader(isr);
            String line = null;
            while ((line = br.readLine()) != null) {
                String[] split = line.split("----");
                String key = split[0];
                String val = split[1];
                //if (null == key) key = "";
                //if(null == val) val ="";
                jedis.set(key,val);
                System.out.println(i);
                System.out.println(Thread.currentThread().getName() + ":::" + line);
                System.out.println(Thread.currentThread().getName() + ":::" + key+"----"+val);
                i++;
            }
            br.close();
        }
    
    }
    
    import java.io.File;
    import java.io.IOException;
    import java.util.List;
    
    public class FavThreadUtil implements Runnable {
        private List<File> fileList;
        public FavThreadUtil(List fileList) {
            this.fileList = fileList;
        }
        @Override
        public void run() {
            for(File file : fileList){
                try {
                    FavFileUtil.readFile(file);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    
    }
    
    展开全文
  • 在写之前先声明,本文是基于之前在博客园网站上检索到的一份JAVA多线程读写文件的示例,我在写自己的程序时是在那位作者写的基础上做了改良,但已不记得原文的地址。如果有知情者,烦请帖出地址,我在此文上加入引用...

    在写之前先声明,本文是基于之前在博客园网站上检索到的一份JAVA多线程读写文件的示例,我在写自己的程序时是在那位作者写的基础上做了改良,但已不记得原文的地址。如果有知情者,烦请帖出地址,我在此文上加入引用或转载。

    本程序是基于这么一种考虑,某系统后台有个将近2G大小的日志文件,你用任何编辑器去打开它,都将会很困难。针对这样的大文件解析处理,解决方案是使用多个线程,分割读取指定的大文件。获取我们所需要的信息。不多说,上代码了,有注释可以帮助理解。

    Java代码  5dcc728ba911b6562957664715830fca.png

    package com.thread.multipl.mysolution;

    import java.io.IOException;

    import java.io.RandomAccessFile;

    import java.util.concurrent.CountDownLatch;

    /**

    * 这个线程用来读取文件,当获取到指定关键字时,在指定的对象加1

    * @author 刘峰管理2

    *

    */

    public class ReadThread extends Thread{

    //定义字节数组(取水的竹筒)的长度

    private final int BUFF_LEN = 256;

    //定义读取的起始点

    private long start;

    //定义读取的结束点

    private long end;

    //将读取到的字节输出到raf中  randomAccessFile可以理解为文件流,即文件中提取指定的一部分的包装对象

    private RandomAccessFile raf;

    //线程中需要指定的关键字

    private String keywords;

    //此线程读到关键字的次数

    private int curCount = 0;

    /**

    * jdk1.5开始加入的类,是个多线程辅助类

    * 用于多线程开始前统一执行操作或者多线程执行完成后调用主线程执行相应操作的类

    */

    private CountDownLatch doneSignal;

    public ReadThread(long start, long end, RandomAccessFile raf,String keywords,CountDownLatch doneSignal){

    this.start = start;

    this.end = end;

    this.raf  = raf;

    this.keywords = keywords;

    this.doneSignal = doneSignal;

    }

    public void run(){

    try {

    raf.seek(start);

    //本线程负责读取文件的大小

    long contentLen = end - start;

    //定义最多需要读取几次就可以完成本线程的读取

    long times = contentLen / BUFF_LEN+1;

    System.out.println(this.toString() + " 需要读的次数:"+times);

    byte[] buff = new byte[BUFF_LEN];

    int hasRead = 0;

    String result = null;

    for (int i = 0; i 

    //之前SEEK指定了起始位置,这里读入指定字节组长度的内容,read方法返回的是下一个开始读的position

    hasRead = raf.read(buff);

    //如果读取的字节数小于0,则退出循环! (到了字节数组的末尾)

    if (hasRead 

    break;

    }

    result = new String(buff,"gb2312");

    ///             System.out.println(result);

    int count = this.getCountByKeywords(result, keywords);

    if(count > 0){

    this.curCount += count;

    }

    }

    KeyWordsCount kc = KeyWordsCount.getCountObject();

    kc.addCount(this.curCount);

    doneSignal.countDown();//current thread finished! noted by latch object!

    } catch (IOException e) {

    // TODO Auto-generated catch block

    e.printStackTrace();

    }

    }

    public long getStart() {

    return start;

    }

    public void setStart(long start) {

    this.start = start;

    }

    public long getEnd() {

    return end;

    }

    public void setEnd(long end) {

    this.end = end;

    }

    public RandomAccessFile getRaf() {

    return raf;

    }

    public void setRaf(RandomAccessFile raf) {

    this.raf = raf;

    }

    public int getCountByKeywords(String statement,String key){

    return statement.split(key).length-1;

    }

    public int getCurCount() {

    return curCount;

    }

    public void setCurCount(int curCount) {

    this.curCount = curCount;

    }

    public CountDownLatch getDoneSignal() {

    return doneSignal;

    }

    public void setDoneSignal(CountDownLatch doneSignal) {

    this.doneSignal = doneSignal;

    }

    }

    Java代码  5dcc728ba911b6562957664715830fca.png

    package com.thread.multipl.mysolution;

    import java.io.File;

    import java.io.RandomAccessFile;

    import java.util.concurrent.CountDownLatch;

    public class MultiReadTest {

    /**

    * 多线程读取文件测试

    * @param args

    */

    public static void main(String[] args) {

    // TODO Auto-generated method stub

    final int DOWN_THREAD_NUM = 10;//起10个线程去读取指定文件

    final String OUT_FILE_NAME = "d:\\倚天屠龙记.txt";

    final String keywords = "无忌";

    //jdk1.5线程辅助类,让主线程等待所有子线程执行完毕后使用的类,

    //另外一个解决方案:自己写定时器,个人建议用这个类

    CountDownLatch doneSignal = new CountDownLatch(DOWN_THREAD_NUM);

    RandomAccessFile[] outArr = new RandomAccessFile[DOWN_THREAD_NUM];

    try{

    long length = new File(OUT_FILE_NAME).length();

    System.out.println("文件总长度:"+length+"字节");

    //每线程应该读取的字节数

    long numPerThred = length / DOWN_THREAD_NUM;

    System.out.println("每个线程读取的字节数:"+numPerThred+"字节");

    //整个文件整除后剩下的余数

    long left = length % DOWN_THREAD_NUM;

    for (int i = 0; i 

    //为每个线程打开一个输入流、一个RandomAccessFile对象,

    //让每个线程分别负责读取文件的不同部分

    outArr[i] = new RandomAccessFile(OUT_FILE_NAME, "rw");

    if (i != 0) {

    //

    //                    isArr[i] = new FileInputStream("d:/勇敢的心.rmvb");

    //以指定输出文件创建多个RandomAccessFile对象

    }

    if (i == DOWN_THREAD_NUM - 1) {

    //                    //最后一个线程读取指定numPerThred+left个字节

    //                  System.out.println("第"+i+"个线程读取从"+i * numPerThred+"到"+((i + 1) * numPerThred+ left)+"的位置");

    new ReadThread(i * numPerThred, (i + 1) * numPerThred

    + left, outArr[i],keywords,doneSignal).start();

    } else {

    //每个线程负责读取一定的numPerThred个字节

    //                  System.out.println("第"+i+"个线程读取从"+i * numPerThred+"到"+((i + 1) * numPerThred)+"的位置");

    new ReadThread(i * numPerThred, (i + 1) * numPerThred,

    outArr[i],keywords,doneSignal).start();

    }

    }

    }catch(Exception e){

    e.printStackTrace();

    }

    //      finally{

    //

    //      }

    //确认所有线程任务完成,开始执行主线程的操作

    try {

    doneSignal.await();

    } catch (InterruptedException e) {

    // TODO Auto-generated catch block

    e.printStackTrace();

    }

    //这里需要做个判断,所有做read工作线程全部执行完。

    KeyWordsCount k = KeyWordsCount.getCountObject();

    //      Map resultMap = k.getMap();

    System.out.println("指定关键字出现的次数:"+k.getCount());

    }

    }

    Java代码  5dcc728ba911b6562957664715830fca.png

    package com.thread.multipl.mysolution;

    /**

    * 统计关键字的对象

    * @author 刘峰管理2

    *

    */

    public class KeyWordsCount {

    private static KeyWordsCount kc;

    private int count = 0;

    private KeyWordsCount(){

    }

    public static synchronized KeyWordsCount getCountObject(){

    if(kc == null){

    kc = new KeyWordsCount();

    }

    return kc;

    }

    public synchronized void  addCount(int count){

    System.out.println("增加次数:"+count);

    this.count += count;

    }

    public int getCount() {

    return count;

    }

    public void setCount(int count) {

    this.count = count;

    }

    }

    运行结果如下:

    引用

    文件总长度:2012606字节

    每个线程读取的字节数:201260字节

    Thread[Thread-0,5,main] 需要读的次数:787

    Thread[Thread-1,5,main] 需要读的次数:787

    Thread[Thread-2,5,main] 需要读的次数:787

    Thread[Thread-3,5,main] 需要读的次数:787

    Thread[Thread-4,5,main] 需要读的次数:787

    Thread[Thread-5,5,main] 需要读的次数:787

    Thread[Thread-6,5,main] 需要读的次数:787

    Thread[Thread-7,5,main] 需要读的次数:787

    Thread[Thread-8,5,main] 需要读的次数:787

    Thread[Thread-9,5,main] 需要读的次数:787

    增加次数:0

    增加次数:146

    增加次数:432

    增加次数:539

    增加次数:587

    增加次数:717

    增加次数:631

    增加次数:467

    增加次数:665

    增加次数:538

    指定关键字出现的次数:4722

    我用10个线程去解析金庸大师写的《倚天屠龙记》,“无忌”这个词在这部小说中一共出现了4722次。实在找不到再大一些的文件了。倚天屠龙记.txt的大小4M出头。

    关于CountDownLatch类的作用说明:

    在API文档中,已经说明是一个辅助类。用于控制主线程与子线程之间切换的一个工具类。用法网上去搜下。ITEYE里也有人讨论过。我在这里使用它解决这样的问题:在确保10个线程都完成文件的解析工作后,系统调用主线程做剩下该做的事情,即:输出“出现的次数”。不确保这点的话,会导致执行完第4个线程,后面的线程还没开始,系统已经做最后一步输出统计结果,这样就达不到我们要的效果。这里解决方案有另一个简单的,自己写个计数器,从10记到1,10个线程嘛。这个看个人喜好吧。

    原文:http://babystudyjava.iteye.com/blog/1732814

    展开全文
  • Java多线程读写文件

    千次阅读 2020-04-17 20:56:56
    读写文件是IO密集型任务 过多的线程执行同一个任务,并不一定能提高效率,因为线程切换,需要耗时。再比如IO密集型任务,IO是瓶颈,并不是线程越多,IO会越快。 开多线程去执行任务,需要综合考虑实际情况。 二、...

    一、背景知识

    1. 多线程可以提高任务的执行效率,尤其是CPU计算密集型任务
    2. 读写文件是IO密集型任务
    3. 过多的线程执行同一个任务,并不一定能提高效率,因为线程切换,需要耗时。再比如IO密集型任务,IO是瓶颈,并不是线程越多,IO会越快。
    4. 开多线程去执行任务,需要综合考虑实际情况。

    二、问题
    最近项目中遇到,安装APK(其中有拷贝apk文件到具体路劲的逻辑),考虑到优化,缩短这里的apk文件拷贝时间。优化过程,使用了断点拷贝和多线程拷贝。

    1. 断点拷贝:使用Java的随机读取RandomAccessFile来实现。通过可以seek()到上次断点的位置,接着继续读写。

          /**
       * 随机读取,支持断点读写
       *
       * @param src 源文件
       * @param dst 目标文件
       * @throws IOException
       */
      @WorkerThread
      public static void copyFileRandomSingleThread(String src, String dst) throws IOException {
      
          RandomAccessFile srcFile = new RandomAccessFile(src, "rw");
          RandomAccessFile dstFile = new RandomAccessFile(dst, "rw");
      
          try {
              long currentDstLength = dstFile.length();
              srcFile.seek(currentDstLength);
              dstFile.seek(currentDstLength);
              Log.d(TAG, "Read " + src + " and Write " + dst + " from " + currentDstLength);
      
              byte[] buffer = new byte[8192];
              int read = -1;
              while ((read = srcFile.read(buffer)) != -1) {
                  dstFile.write(buffer, 0, read);
              }
          } catch (IOException e) {
              Log.d(TAG, "copyFileRandom exception, ", e);
          } finally {
              try {
                  srcFile.close();
              } catch (IOException e) {
                  Log.d(TAG, "copyFileRandom close exception, ", e);
              }
              try {
                  dstFile.close();
              } catch (IOException e) {
                  Log.d(TAG, "copyFileRandom close exception, ", e);
              }
          }
      
      
      }
      
      
    2. 多线程拷贝(如果必须在多线程拷贝完文件后,再去做其他任务,此处需要用到CountDownlatch进行同步)
      将File分片,然后每个线程去读不同的片。

      /**
       * 多线程拷贝文件
       *
       * @param sourcePath
       * @param targetPath
       * @param threadNums
       */
      private static void copyFileRandomMultiThread(String sourcePath, String targetPath, int threadNums) {
          long totalFileLength = new File(sourcePath).length();
          long currentTargetLength = new File(targetPath).length();
      
      
          long segmentLength = (totalFileLength - currentTargetLength) / (threadNums);
          //同步锁,全部写完,才能继续下一步处理
          CountDownLatch mCountDownLatch;
          //如果不可以整除,则需要多一个线程
          if (totalFileLength % threadNums != 0) {
              mCountDownLatch = new CountDownLatch(threadNums + 1);
          } else {
              mCountDownLatch = new CountDownLatch(threadNums);
          }
      
          int i;
          Log.d(TAG, "threadNums-->" + mCountDownLatch.getCount());
          long start = System.currentTimeMillis();
          for (i = 0; i < threadNums; i++) {
      
              sThreadPool.execute(new CopyFileRunnable(mCountDownLatch, sourcePath, targetPath, i * segmentLength + currentTargetLength, (i + 1) * segmentLength));
      
          }
      
          if (totalFileLength % threadNums != 0) {
              sThreadPool.execute(new CopyFileRunnable(mCountDownLatch, sourcePath, targetPath, i * segmentLength + currentTargetLength, totalFileLength));
          }
          try {
              mCountDownLatch.await();
              Log.d(TAG, "multi thread copyFile costs-->" + (System.currentTimeMillis() - start));
          } catch (InterruptedException e) {
              Log.d(TAG, "countDownLatch exception: ", e);
          }
      }
      
      
      private static class CopyFileRunnable implements Runnable {
          private RandomAccessFile in;
          private RandomAccessFile out;
          private long start;
          private long end;
          private CountDownLatch latch;
      
          /**
           * @param countDownLatch 同步锁
           * @param in             源文件地址
           * @param out            目标文件地址
           * @param start          分段复制的开始位置
           * @param end            分段复制的结束位置
           */
          CopyFileRunnable(CountDownLatch countDownLatch, String in, String out,
                           long start, long end) {
              this.start = start;
              this.end = end;
              try {
                  this.in = new RandomAccessFile(in, "rw");
                  this.out = new RandomAccessFile(out, "rw");
              } catch (FileNotFoundException e) {
                  e.printStackTrace();
              }
      
              this.latch = countDownLatch;
          }
      
          @Override
          public void run() {
              try {
                  in.seek(start);
                  out.seek(start);
                  android.util.Log.d(TAG, "multi thread from: " + start + "; end:" + end);
                  int hasRead = 0;
                  byte[] buff = new byte[8 * 1024];
                  while (start < end && (hasRead = in.read(buff)) != -1) {
                      start += hasRead;
                      out.write(buff, 0, hasRead);
                  }
      
              } catch (IOException e) {
                  e.printStackTrace();
              } finally {
                  try {
                      in.close();
                      out.close();
                  } catch (IOException e) {
                      e.printStackTrace();
                  }
      
                  latch.countDown();
              }
      
          }
      }
      
    3. 完整的程序代码

      public class Utils {
      
      private static final String TAG = Utils.class.getSimpleName();
      
      private static final int CPU_SIZE = Runtime.getRuntime().availableProcessors();
      private static final int CORE_POOL_SIZE = 2 * CPU_SIZE + 1;
      private static final int MAX_POLL_SIZE = CORE_POOL_SIZE;
      private static final ThreadFactory THREAD_FACTORY = new ThreadFactory() {
          private AtomicInteger index = new AtomicInteger(1);
      
          @Override
          public Thread newThread(@NonNull Runnable r) {
      
              Thread thread = new Thread(r);
              thread.setName("Sandbox_Utils-thread-" + index.getAndIncrement());
              return thread;
          }
      };
      private static final int DEFAULT_THREAD_NUM = 1;
      private static ExecutorService sThreadPool = new ThreadPoolExecutor(CORE_POOL_SIZE, MAX_POLL_SIZE, 60L, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(128), THREAD_FACTORY);
      
      
      /**
       * 随机读取,支持断点读写
       *
       * @param src 源文件
       * @param dst 目标文件
       * @throws IOException
       */
      @WorkerThread
      public static void copyFileRandomSingleThread(String src, String dst) throws IOException {
      
          RandomAccessFile srcFile = new RandomAccessFile(src, "rw");
          RandomAccessFile dstFile = new RandomAccessFile(dst, "rw");
      
          try {
              long currentDstLength = dstFile.length();
              srcFile.seek(currentDstLength);
              dstFile.seek(currentDstLength);
              Log.d(TAG, "Read " + src + " and Write " + dst + " from " + currentDstLength);
      
              byte[] buffer = new byte[8192];
              int read = -1;
              while ((read = srcFile.read(buffer)) != -1) {
                  dstFile.write(buffer, 0, read);
              }
          } catch (IOException e) {
              Log.d(TAG, "copyFileRandom exception, ", e);
          } finally {
              try {
                  srcFile.close();
              } catch (IOException e) {
                  Log.d(TAG, "copyFileRandom close exception, ", e);
              }
              try {
                  dstFile.close();
              } catch (IOException e) {
                  Log.d(TAG, "copyFileRandom close exception, ", e);
              }
          }
      
      
      }
      
      
      /**
       * copy 文件单线程
       *
       * @param sourcePath
       * @param targetPath
       */
      public static void copyFileRandom(String sourcePath, String targetPath) {
          copyFileRandom(sourcePath, targetPath, 1);
      }
      
      /**
       * @param sourcePath 源文件路径
       * @param targetPath 目标文件路径
       * @param threadNums 设定的线程数
       */
      @WorkerThread
      public static void copyFileRandom(String sourcePath, String targetPath, int threadNums) {
      
          if (threadNums <= 0) {
              threadNums = DEFAULT_THREAD_NUM;
          }
      
          //单线程拷贝
          if (threadNums == 1) {
              try {
                  copyFileRandomSingleThread(sourcePath, targetPath);
              } catch (IOException e) {
                  e.printStackTrace();
              }
              //多线程拷贝
          } else {
              copyFileRandomMultiThread(sourcePath, targetPath, threadNums);
          }
      
      
      }
      
      /**
       * 多线程拷贝文件
       *
       * @param sourcePath
       * @param targetPath
       * @param threadNums
       */
      private static void copyFileRandomMultiThread(String sourcePath, String targetPath, int threadNums) {
          long totalFileLength = new File(sourcePath).length();
          long currentTargetLength = new File(targetPath).length();
      
      
          long segmentLength = (totalFileLength - currentTargetLength) / (threadNums);
          //同步锁,全部写完,才能继续下一步处理
          CountDownLatch mCountDownLatch;
          //如果不可以整除,则需要多一个线程
          if (totalFileLength % threadNums != 0) {
              mCountDownLatch = new CountDownLatch(threadNums + 1);
          } else {
              mCountDownLatch = new CountDownLatch(threadNums);
          }
      
          int i;
          Log.d(TAG, "threadNums-->" + mCountDownLatch.getCount());
          long start = System.currentTimeMillis();
          for (i = 0; i < threadNums; i++) {
      
              sThreadPool.execute(new CopyFileRunnable(mCountDownLatch, sourcePath, targetPath, i * segmentLength + currentTargetLength, (i + 1) * segmentLength));
      
          }
      
          if (totalFileLength % threadNums != 0) {
              sThreadPool.execute(new CopyFileRunnable(mCountDownLatch, sourcePath, targetPath, i * segmentLength + currentTargetLength, totalFileLength));
          }
          try {
              mCountDownLatch.await();
              Log.d(TAG, "multi thread copyFile costs-->" + (System.currentTimeMillis() - start));
          } catch (InterruptedException e) {
              Log.d(TAG, "countDownLatch exception: ", e);
          }
      }
      
      
      private static class CopyFileRunnable implements Runnable {
          private RandomAccessFile in;
          private RandomAccessFile out;
          private long start;
          private long end;
          private CountDownLatch latch;
      
          /**
           * @param countDownLatch 同步锁
           * @param in             源文件地址
           * @param out            目标文件地址
           * @param start          分段复制的开始位置
           * @param end            分段复制的结束位置
           */
          CopyFileRunnable(CountDownLatch countDownLatch, String in, String out,
                           long start, long end) {
              this.start = start;
              this.end = end;
              try {
                  this.in = new RandomAccessFile(in, "rw");
                  this.out = new RandomAccessFile(out, "rw");
              } catch (FileNotFoundException e) {
                  e.printStackTrace();
              }
      
              this.latch = countDownLatch;
          }
      
          @Override
          public void run() {
              try {
                  in.seek(start);
                  out.seek(start);
                  android.util.Log.d(TAG, "multi thread from: " + start + "; end:" + end);
                  int hasRead = 0;
                  byte[] buff = new byte[8 * 1024];
                  while (start < end && (hasRead = in.read(buff)) != -1) {
                      start += hasRead;
                      out.write(buff, 0, hasRead);
                  }
      
              } catch (IOException e) {
                  e.printStackTrace();
              } finally {
                  try {
                      in.close();
                      out.close();
                  } catch (IOException e) {
                      e.printStackTrace();
                  }
      
                  latch.countDown();
              }
      
          }
      }
      
      
      
      
      
    展开全文
  • 主要为大家详细介绍了java使用多线程读取超大文件,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
  • 主要为大家详细介绍了java多线程有序读取同一个文件,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
  • java多线程读写文件

    千次阅读 2018-04-07 23:11:06
    一、引言 使用java读写文件是日常工作中需要经常使用的技术。为了提高文件写出分析和写出效率,本文采用多线程实现多文件解析和写出。具体实现如下:二、文件读写工具类package ...
  • 多线程文件读写操作(java),提高对文件读写效率。
  • 主要为大家详细介绍了Java jdbc批量多线程读取CVS文件入库,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
  • Java多线程文件:package com.myjava;import java.io.BufferedReader;import java.io.FileNotFoundException;import java.io.FileReader;import java.io.IOException;import java.util.ArrayList;import java.util...
  • import java.io.*; import java.util.ArrayList; import java.util.List; /** * @author chenchbj */ public class ReadUtil implements Serializable { private static final long serialVersionUID = -...
  • 针对这样的大文件解析处理,解决方案是使用线程,分割读取指定的大文件。获取我们所需要的信息。不说,上代码了,有注释可以帮助理解。 2.代码 package com.thread.multipl.mysolution; import java.io...
  • JAVA的标准I/O中,提供了基于流的I/O实现,即InputStream和OutputStream。这种基于流的实现以字节为单位处理数据。NIO是New I/O的简称,表示一套新的JAVA I/O标准。在Jdk 1.4中开始引入,它具有以下特性: 为所有...
  • RandomAccessFile 是 Java 输入/输出流体系中功能最丰富的文件内容访问类,它提供了众多的方法来访问文件内容,它既可以读取文件内容,也可以向文件输出数据。由于 RandomAccessFile 可以从任意位置访问文件,所以在...
  • 让我们再举一个例子,它与你的类似,但实际上可以提供一些好处:假设我想在一个巨大的单词列表中搜索某个单词的出现(这个列表甚至可能来自一个磁盘文件,但是像我一样说,由一个线程读取).假设我可以像你的例子一样使用3...
  • java 文件多线程并行读取
  • java多线程读写同一个文件

    千次阅读 2021-02-12 10:51:57
    本文提供java多线程分别定时读写同一个文件的样例,其中两个线程,一个每分钟写入当前时间到指定文件,另一个线程读出每分钟新写的内容。使用简单的Thread.sleep技术实现定时package test.thread;import java.io....
  • Java 单线程复制文件和使用RandomAccessFile多线程复制文件的比较,对应博客地址为http://blog.csdn.net/zmichealchow/article/details/38687431
  • java 多线程读取多个文件

    千次阅读 2019-01-02 10:49:34
    package ... import java.io.*; import java.util.List; import java.util.concurrent.CountDownLatch; ... * 多线程读取多个文件 */ public class FileThread extends Thread{ p...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 303,963
精华内容 121,585
关键字:

java多线程读取文件

java 订阅