Hello.
The idea is to create a range based on the file size, each range on its own stream, i.e. if for example the file size is 100,000 bytes, and we divide this size into several streams, then we get ranges of 0-1000, 1001-2000,2001-3000, etc. I wrote my own algorithm.
public List<String> getThreadsDiapason(int startBytes, int endBytes, int c_thread) { int step = (int)(endBytes / c_thread); List<Integer> temp_start = new ArrayList<>(); List<Integer> temp_end = new ArrayList<>(); temp_start.add(startBytes); temp_end.add(step); try { for(int i = 1; i < c_thread; i++) { temp_start.add(i,temp_end.get(i - 1) + 1); temp_end.add(i,temp_end.get(i - 1) + step); } } catch (Exception ex) { Log.e("getThreadsDiapason", ex.getMessage()); } int last_value = temp_end.get(c_thread-1) + (endBytes - temp_end.get(c_thread-1)); temp_end.set(c_thread-1,last_value); List<String> finalList = new ArrayList<>(); try { for(int i = 0; i < c_thread; i++) { finalList.add(temp_start.get(i)+"-"+temp_end.get(i)); } } catch (Exception ex) { Log.e("getThreadsDiapason",ex.getMessage()); } return finalList; } After it is necessary to run this list, create threads with parameters equal to each of the cells of the list. Wrote the method described below:
public void threadedDownload(final String url,final String path,final int size) throws Exception { int threads_count = 32; final int stock_buffer = 4096 * threads_count; final List<String> threadsDiap = getThreadsDiapason(0,size,threads_count); final List<Thread> threadList = new ArrayList<>(); for(int i = 0; i < threads_count; i++) { final int diap_i = i; Thread t = new Thread(new Runnable() { @Override public void run() { byte[] buffer = new byte[stock_buffer]; int bytesRead = -1; try { System.out.println("Thread "+diap_i+" Started : " + threadsDiap.get(diap_i)); HttpURLConnection conn = null; FileOutputStream fileOutputStream = null; try { conn = (HttpURLConnection)new URL(url).openConnection(); } catch (IOException e) { Log.e("threadedDownload",e.getMessage()); } conn.setDoInput(true); conn.setConnectTimeout(100000); conn.setRequestProperty("Range", "bytes="+threadsDiap.get(diap_i)); fileOutputStream = new FileOutputStream(path ,true); conn.connect(); InputStream inputStream = conn.getInputStream(); while ((bytesRead = inputStream.read(buffer)) != -1) { fileOutputStream.write(buffer, Integer.parseInt(threadsDiap.get(diap_i).split("-")[0]), bytesRead); } fileOutputStream.flush(); fileOutputStream.close(); System.out.println("Thread "+diap_i+" Ended : " + threadsDiap.get(diap_i)); }catch (Exception ex) { Log.e("Error",ex.getMessage()); } } }); threadList.add(t); } final List<Thread> finalThreadList = threadList; new Thread(new Runnable() { @Override public void run() { for(int i = 0; i < finalThreadList.size(); i++) { finalThreadList.get(i).start(); } } }).start(); } But when I start, I get errors:
E/Error: length=131072; regionStart=84024925; regionLength=1360 E/Error: length=131072; regionStart=33609970; regionLength=894 E/Error: length=131072; regionStart=201659820; regionLength=1360 E/Error: length=131072; regionStart=235269790; regionLength=1580 E/Error: length=131072; regionStart=100829910; regionLength=2048 E/Error: length=131072; regionStart=168049850; regionLength=2048 E/Error: length=131072; regionStart=117634895; regionLength=2048 E/Error: length=131072; regionStart=50414955; regionLength=1582 E/Error: length=131072; regionStart=184854835; regionLength=1580 E/Error: length=131072; regionStart=16804985; regionLength=1589 E/Error: length=131072; regionStart=319294715; regionLength=1580 E/Error: length=131072; regionStart=302489730; regionLength=2048 E/Error: length=131072; regionStart=285684745; regionLength=1580 E/Error: length=131072; regionStart=268879760; regionLength=2048 E/Error: length=131072; regionStart=369709670; regionLength=1360 E/Error: length=131072; regionStart=470539580; regionLength=1580 E/Error: length=131072; regionStart=252074775; regionLength=1580 E/Error: length=131072; regionStart=67219940; regionLength=2048 E/Error: length=131072; regionStart=420124625; regionLength=1580 E/Error: length=131072; regionStart=386514655; regionLength=1580 E/Error: length=131072; regionStart=453734595; regionLength=2048 E/Error: length=131072; regionStart=520954535; regionLength=1580 E/Error: length=131072; regionStart=436929610; regionLength=1580 E/Error: length=131072; regionStart=487344565; regionLength=2048 E/Error: length=131072; regionStart=336099700; regionLength=2048 E/Error: length=131072; regionStart=403319640; regionLength=1580 E/Error: length=131072; regionStart=537759529; regionLength=1580 E/Error: length=131072; regionStart=504149550; regionLength=1580 E/Error: length=131072; regionStart=151244865; regionLength=2048 E/Error: length=131072; regionStart=352904685; regionLength=1580 E/Error: length=131072; regionStart=218464805; regionLength=1580 E/Error: length=131072; regionStart=134439880; regionLength=1580 I tried different ways, the latter is probably the most correct, specify the offset and write to the fileOutputStream.write(buffer, Integer.parseInt(threadsDiap.get(diap_i).split("-")[0]), bytesRead); However, it does not work correctly.
Guide me on the right path.