技术开发 频道

随机访问类RandomAccessFile多线程下载

  【IT168 技术】随机访问类RandomAccessFile。

  输入流FileInputStream和输出流 FileOutputStream,实现的是对磁盘文件的顺序读写,而且读写要分别创建不同对象。

  相比之下RandomAccessFile类则可对文件实现随机读写操作。

  RandomAccessFile对象的文件位置指针遵循下面的规律:

  •   新建RandomAccessFile对象的文件位置指针位于文件的开头处。
  •   每次读写操作之后,文件位置的指针都相应后移到读写的字节数。
  •   可以通过getFilePointer方法来获得文件位置指针的位置,通过seek方法来设置文件指针的位置。

  如果某个文件有30个字节,读取数据过程中,从20-30读取,用skip( )//跳过方法,但在读取的过程中,前面的字节都被删除掉了,如果用户有这样的需求,先读取10-20字节,之后再读1-10之间的数,再20-30之间。

  多线程下载

public  void threadDownLoad(String path,int threadSize) throws Exception{
        URL url
= new URL(path);
        HttpURLConnection connection
= (HttpURLConnection) url.openConnection();
        connection.setRequestMethod(
"GET");
        
if(connection.getResponseCode() != 200){
            
throw new RuntimeException("ResponseCode != 200");
        }
        
//要下载的总大小
        int dataLength = connection.getContentLength();
        connection.disconnect();
        
//线程数
        threadSize = threadSize == 0 ? 5 : threadSize;
        threadSize
= dataLength % threadSize == 0 ? threadSize : threadSize+1;
        
//每个线程块要下载的数量
        int blockSize = dataLength / threadSize;
        String newFileName
= rename(path);
        System.out.println(
""+threadSize+"个线程开始下载");
        
for(int i=0;i<threadSize;i++){
            RandomAccessFile accessFile
= new RandomAccessFile(newFileName, "rw");
            
int startSize =blockSize * i;
             accessFile.seek(startSize);
            Thread thread
= new Thread(new DownLoad(startSize, path, blockSize, accessFile,i+1));
            thread.start();
        }
    }

 

  定义的线程下载类

private class DownLoad implements Runnable{
        
private String path;
        
private RandomAccessFile accessFile;
        
private int startSize;
        
private int blockSize;
        
private int threadName;
        
public DownLoad(int startSize,String path,int blockSize,RandomAccessFile accessFile,int threadName)
{            
this.path = path;
            
this.accessFile = accessFile;
            
this.startSize = startSize;
            
this.blockSize = blockSize;
            
this.threadName = threadName;
        }
        @Override
        
public void run() {
            
try {
                System.out.println(
"线程"+threadName+"开始下载.....");
                URL url
= new URL(path);
                HttpURLConnection connection
= (HttpURLConnection) url.openConnection();
                connection.setRequestMethod(
"GET");
                connection.setReadTimeout(
6*1000);
                connection.setRequestProperty(
"Range", "bytes=" + startSize + "-");
                
if(connection.getResponseCode()!=206){
                    
throw new RuntimeException("ResponseCode != 206");
                }
                InputStream inputStream
= connection.getInputStream();
                inputStream
= new BufferedInputStream(inputStream);
                
byte[] buffer = new byte[1024];
                
int len = -1;
                
int length = 0;
                
while(length < blockSize && ((len = inputStream.read(buffer)) != -1)){
                    accessFile.write(buffer,
0, len);
                    length
+= len;
                }                accessFile.close();
                inputStream.close();
                connection.disconnect();
                System.out.println(
"线程"+threadName+"下载成功!");
            }
catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
0