多线程文件下载简单实现(1)

1.Connection接口

public interface Connection {
    /**
     * @Author xuyangyang
     * @Describe  给定开始和结束位置, 读取数据, 返回值是字节数组
     * @Date 2017/6/7
     * @Params 
     * @Return 
     */
    byte[] read(int startPos, int endPos) throws IOException ;


    /**
     * @Author xuyangyang
     * @Describe 得到数据内容的长度
     * @Date 2017/6/7
     * @Params
     * @Return
     */
    int getContentLength();


    /**
     * @Author xuyangyang
     * @Describe  关闭连接
     * @Date 2017/6/7
     * @Params
     * @Return
     */
    void close();
}

2.ConnectionManager管理接口

public interface ConnectionManager {
    /**
     * @Author xuyangyang
     * @Describe 给定一个url , 打开一个连接
     * @Date 2017/6/7
     * @Params 
     * @Return 
     */
    Connection open(String url) throws ConnectionException;
}

3.实现ConnectionManager,根据url打开一个连接,返回Connection对象

public class ConnectionManagerImpl implements ConnectionManager {
    @Override
    public Connection open(String url) throws ConnectionException {
        return new ConnectionImpl(url);
    }
}

4.具体的实现类

public class ConnectionImpl implements Connection {

    URL url;
    static final int BUFFER_SIZE = 1024;


    public ConnectionImpl(String _url) {
        try {
            url = new URL(_url);
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }

    }

    @Override
    public byte[] read(int startPos, int endPos) throws IOException {

        HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();

        httpURLConnection.setRequestProperty("Range", "bytes=" + startPos + "-" + endPos);

        InputStream in = httpURLConnection.getInputStream();

        byte[] bytes = new byte[BUFFER_SIZE];

        int totalLen = endPos - startPos + 1;

        ByteArrayOutputStream baos = new ByteArrayOutputStream();

        while (baos.size() < totalLen) {
            int len = in.read(bytes);
            if (len < 0) {
                break;
            }
            baos.write(bytes, 0, len);
        }

        if (baos.size() > totalLen) {
            byte[] data = baos.toByteArray();
            return Arrays.copyOf(data, totalLen);
        }

        return baos.toByteArray();
    }

    @Override
    public int getContentLength() {
        URLConnection con;
        try {
            con = url.openConnection();

            return con.getContentLength();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return -1;
    }

    @Override
    public void close() {

    }
}

5.简单的测试

public class ConnectionTest {
    @Before
    public void setUp() throws Exception {
    }

    @After
    public void tearDown() throws Exception {
    }


    @Test
    public void testContentLength() throws Exception{
        ConnectionManager connMan = new ConnectionManagerImpl();
        Connection conn = connMan.open("http://www.hinews.cn/pic/0/13/91/26/13912621_821796.jpg");
        Assert.assertEquals(35470, conn.getContentLength());
    }

    @Test
    public void testRead() throws Exception{

        ConnectionManager connMan = new ConnectionManagerImpl();
        Connection conn = connMan.open("http://www.hinews.cn/pic/0/13/91/26/13912621_821796.jpg");

        byte[] data = conn.read(0, 35469);

        Assert.assertEquals(35470, data.length);

        data = conn.read(0, 1023);

        Assert.assertEquals(1024, data.length);

        data = conn.read(1024, 2023);

        Assert.assertEquals(1000, data.length);

        // 测试不充分,没有断言内容是否正确
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值