1.Get方式提交数据
**StreamTool类**
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
public class StreamTool {
public static String readStream(InputStream inputStream) throws IOException {
//定义 一个内存输出流
ByteArrayOutputStream byteArrayOutputStream=new ByteArrayOutputStream();
int len=-1;
byte[]buffer=new byte[1024];
while ((len=inputStream.read(buffer))!=-1){
byteArrayOutputStream.write(buffer,0,len);
}
inputStream.close();
String content=new String(byteArrayOutputStream.toByteArray());
return content;
}
}
主activity
package com.fengray.ex053;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
public class MainActivity extends AppCompatActivity {
private EditText edUserName,edPassWord;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initviews();
}
public void initviews(){
edUserName=findViewById(R.id.edUserName);
edPassWord=findViewById(R.id.edPassWord);
}
//Get方式提交
public void btnGetClick(View view){
String username=edUserName.getText().toString().trim();
String password=edPassWord.getText().toString().trim();
//定义get方式要提交的路径
final String path="http://192.168.1.64/******username="+username+"&password="+password;
//获取Url对象
new Thread(){
@Override
public void run() {
URL url= null;
try {
url = new URL(path);
//获取HTTPURLConnection对象
HttpURLConnection connection=(HttpURLConnection)url.openConnection();
//设置Connection访问方式
connection.setRequestMethod("GET");
//设置超时时间
connection.setConnectTimeout(5000);
//获取返回的状态码
int code=connection.getResponseCode();
//判断状态码
if (code==200){
//获取流
InputStream inputStream=connection.getInputStream();
//
String content= StreamTool.readStream(inputStream);
//将服务器返回的数据返回到Toast里,不能再子线程上更新UI
showToast(content);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}.start();
}
//Post方式提交
public void btnPostClick(View view){
String username=edUserName.getText().toString().trim();
String password=edPassWord.getText().toString().trim();
}
//封装一个Toast方法,该toast方法执行在主线程当中
public void showToast(final String content){
runOnUiThread(new Runnable() {
@Override
public void run() {
//该方法一定执行在主线程的
Toast.makeText(getApplicationContext(), content, Toast.LENGTH_SHORT).show();
}
});
}
}
2.Post方式提交数据
get方式和post方式的区别
- 1、路径不同
- 2、请求方式,post要自己组拼请求体的内容,post方式比get方式多了2个头信息,content-length,content-type
- 3、通过请求体的方式把数据写歌服务器,以流的形式
仅仅修改postClick方法
//Post方式提交
public void btnPostClick(View view){
//获取Url对象
new Thread(){
@Override
public void run() {
URL url= null;
String username=edUserName.getText().toString().trim();
String password=edPassWord.getText().toString().trim();
//定义post方式要提交的路径
final String path="http://192.168.1.64/******";//无需组拼
try {
//定义请求体
String data="username="+username+"&password="+password+"";
url = new URL(path);
//获取HTTPURLConnection对象
HttpURLConnection connection=(HttpURLConnection)url.openConnection();
//设置Connection访问方式
connection.setRequestMethod("POST");
//设置超时时间
connection.setConnectTimeout(5000);
//要多设置两个请求头信息
connection.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
connection.setRequestProperty("Content-Length",data.length()+"");
//把组拼好的数据提交给服务器
connection.setDoInput(true);//设置一个标记允许输出
//提交
connection.getOutputStream().write(data.getBytes());
//获取返回的状态码
int code=connection.getResponseCode();
//判断状态码
if (code==200){
//获取流
InputStream inputStream=connection.getInputStream();
//
String content= StreamTool.readStream(inputStream);
//将服务器返回的数据返回到Toast里,不能再子线程上更新UI
showToast(content);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}.start();
}
3.HttpClient方式的get方式提交数据(方法已过时)
sdk6.0以后取消了HttpClient,设置android SDK的编译版本为23时,且使用了httpClient相关类的库项目,会出现有一些类找不到的错误。
解决方法有两种:第一种方法实测可用且为最优解
1.在相应的module下的build.gradle中加入:
useLibrary ‘org.apache.http.legacy’
这条语句一定要加在 android{ } 当中。
如:
android {
useLibrary ‘org.apache.http.legacy’
}
2.将在相应的module下的build.gradle中修改compileSdkVersion的值,设置为更小的sdk版本
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
public class MainActivity extends AppCompatActivity {
private EditText edUserName,edPassWord;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initviews();
}
public void initviews(){
edUserName=findViewById(R.id.edUserName);
edPassWord=findViewById(R.id.edPassWord);
}
//Get方式提交
public void btnGetClick(View view){
String username=edUserName.getText().toString().trim();
String password=edPassWord.getText().toString().trim();
//定义get方式要提交的路径
final String path="http://192.168.1.64/******username="+username+"&password="+password;
//获取Url对象
new Thread(){
@Override
public void run() {
//获取httpClient实例
DefaultHttpClient client=new DefaultHttpClient();
//准备get请求,定义一个httpget实现
HttpGet get=new HttpGet(path);//方法已过时
//执行一个get请求
try {
HttpResponse response=client.execute(get);
//获取服务器返回的状态码
int code=response.getStatusLine().getStatusCode();
if (code ==200){
//获取服务器返回的数据,以流的形式返回
InputStream inputStream=response.getEntity().getContent();
//把流转换成字符串
String content=StreamTool.readStream(inputStream);
//显示在控件上
showToast(content);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}.start();
}
//Post方式提交
public void btnPostClick(View view){
//获取Url对象
new Thread(){
@Override
public void run() {
}
}.start();
}
//封装一个Toast方法,该toast方法执行在主线程当中
public void showToast(final String content){
runOnUiThread(new Runnable() {
@Override
public void run() {
//该方法一定执行在主线程的
Toast.makeText(getApplicationContext(), content, Toast.LENGTH_SHORT).show();
}
});
}
}
3.HttpClient方式的post方式提交数据(方法已过时)
package com.fengray.ex053;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private EditText edUserName,edPassWord;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initviews();
}
public void initviews(){
edUserName=findViewById(R.id.edUserName);
edPassWord=findViewById(R.id.edPassWord);
}
//Get方式提交
public void btnGetClick(View view){
String username=edUserName.getText().toString().trim();
String password=edPassWord.getText().toString().trim();
//定义get方式要提交的路径
final String path="http://192.168.1.64/******username="+username+"&password="+password;
//获取Url对象
new Thread(){
@Override
public void run() {
//获取httpClient实例
DefaultHttpClient client=new DefaultHttpClient();
//准备get请求,定义一个httpget实现
HttpGet get=new HttpGet(path);//方法已过时
//执行一个get请求
try {
HttpResponse response=client.execute(get);
//获取服务器返回的状态码
int code=response.getStatusLine().getStatusCode();
if (code ==200){
//获取服务器返回的数据,以流的形式返回
InputStream inputStream=response.getEntity().getContent();
//把流转换成字符串
String content=StreamTool.readStream(inputStream);
//显示在控件上
showToast(content);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}.start();
}
//Post方式提交
public void btnPostClick(View view){
//获取Url对象
new Thread(){
@Override
public void run() {
String username=edUserName.getText().toString().trim();
String password=edPassWord.getText().toString().trim();
//提交路径
String path="http://192.168.1.64:8080/login/LoginServlet";
//以post方式提交
DefaultHttpClient client = new DefaultHttpClient();
try {
//准备post请求
HttpPost post = new HttpPost(path);
//准备parameters
List<NameValuePair> lists=new ArrayList<>();
//准备namevaluepair
BasicNameValuePair nameValuePair=new BasicNameValuePair("username",username);
BasicNameValuePair pwdValuePair=new BasicNameValuePair("password",password);
//把nameValuePair和pwdValuePair加入到集合中去
lists.add(nameValuePair);
lists.add(pwdValuePair);
//准备Entity
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(lists);
//准备post方式提交的正文,以实体形式提交(键值对形式)
post.setEntity(entity);
HttpResponse response=client.execute(post);
//获取服务器返回的状态码
int code=response.getStatusLine().getStatusCode();
if (code ==200){
//获取服务器返回的数据,以流的形式返回
InputStream inputStream=response.getEntity().getContent();
//把流转换成字符串
String content=StreamTool.readStream(inputStream);
//显示在控件上
showToast(content);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}.start();
}
//封装一个Toast方法,该toast方法执行在主线程当中
public void showToast(final String content){
runOnUiThread(new Runnable() {
@Override
public void run() {
//该方法一定执行在主线程的
Toast.makeText(getApplicationContext(), content, Toast.LENGTH_SHORT).show();
}
});
}
}
4.多线程下载原理(eclipse下实现本例)
多线程下载实现步骤
- 1、获取文件大小
- 2、在客户端创建一个大小和服务器一模一样的文件,提前申请好空间
- 3、每个线程下载的开始位置和结束位置
- 4、开多个线程去下载
- 5、知道每个线程什么时候下载完毕了
package com.fengray;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
public class MultiDownloadMultiDownload {
//定义下载路径
static String path="http://swdlcdn.eastmoney.com/swc8_free_new/dfcft8.exe";
public static void main(String[] args) {
// 获取服务器文件大小,计算每个线程的开始位置和结束位置
URL url;
try {
url = new URL(path);
//获取HTTPURLConnection对象
HttpURLConnection connection=(HttpURLConnection)url.openConnection();
//设置Connection访问方式
connection.setRequestMethod("GET");
//设置超时时间
connection.setConnectTimeout(5000);
//获取返回的状态码
int code=connection.getResponseCode();
//判断状态码
if (code==200){
//获取服务器文件的大小
int length=connection.getContentLength();
System.out.println("length:"+length);
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
打印:
length:57764856
4.JAVA实现多线程下载(eclipse下实现本例)
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
public class MultiDownloadMultiDownload {
//定义下载路径
private static String path="http://swdlcdn.eastmoney.com/swc8_free_new/dfcft8.exe";
//开启线程个数
private static final int threadCount=3;
public static void main(String[] args) {
// 获取服务器文件大小,计算每个线程的开始位置和结束位置
URL url;
try {
url = new URL(path);
//获取HTTPURLConnection对象
HttpURLConnection connection=(HttpURLConnection)url.openConnection();
//设置Connection访问方式
connection.setRequestMethod("GET");
//设置超时时间
connection.setConnectTimeout(5000);
//获取返回的状态码
int code=connection.getResponseCode();
//判断状态码
if (code==200){
//获取服务器文件的大小
int length=connection.getContentLength();
System.out.println("length:"+length);
//创建一个大小和服务器一模一样的文件,目的是吧空间申请出来
RandomAccessFile randomAccessFile=new RandomAccessFile("dfcft8.exe", "rw");//可读可写
randomAccessFile.setLength(length);
//算出每个线程下载的大小
int blockSize=length/threadCount;
//计算每个线程下载的开始和结束位置
for (int i = 0; i < threadCount; i++) {
int startIndex=i*blockSize;//每个线程下载的开始位置
int endIndex=(i+1)*blockSize-1;
//特殊情况就是最后一个线程
if(i==threadCount-1) {
//说明是最后一个线程
endIndex=length-1;
}
//开启线程去服务器下载文件
DownLoadThread downLoadThread= new DownLoadThread(startIndex, endIndex, i);
downLoadThread.start();
}
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//定义线程去服务器下载
private static class DownLoadThread extends Thread{
private int startIndex,endIndex,threadId;
//通过构造方法把每个线程的开始位置和结束位置传递过来
public DownLoadThread(int startIndex,int endIndex,int threadId) {
this.startIndex=startIndex;
this.endIndex=endIndex;
this.threadId=threadId;
}
@Override
public void run() {
// 实现去服务器下载文件的逻辑
try {
URL url = new URL(path);
//获取HTTPURLConnection对象
HttpURLConnection connection=(HttpURLConnection)url.openConnection();
//设置Connection访问方式
connection.setRequestMethod("GET");
//设置超时时间
connection.setConnectTimeout(5000);
//设置一个请求头range(范围)作用是告诉服务器每个线程下载的开始位置和结束位置
connection.setRequestProperty("range", "bytes="+startIndex+"-"+endIndex);
//获取返回的状态码
int code=connection.getResponseCode();
//判断状态码
if (code==206){//206代表请求的资源成功
//创建随机读写文件对象
RandomAccessFile randomAccessFile=new RandomAccessFile("temp.ext", "rw");
//每个线程要从自己的位置写
randomAccessFile.seek(startIndex);
InputStream inputStream=connection.getInputStream();//这里connection只请求了部分资源
//把数据写到文件中
int len=-1;
byte[] buffer=new byte[1024];
while ((len=inputStream.read(buffer))!=-1) {
randomAccessFile.write(buffer,0,len);
}
randomAccessFile.close();
System.out.println("线程ID:"+threadId+"----下载完毕");
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
打印
length:57764856
线程ID:0----下载完毕
线程ID:2----下载完毕
线程ID:1----下载完毕
5.断点续传(eclipse下实现本例)
package com.fengray;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
public class MultiDownloadMultiDownload {
//定义下载路径
private static String path="http://swdlcdn.eastmoney.com/swc8_free_new/dfcft8.exe";
//开启线程个数
private static final int threadCount=3;
public static void main(String[] args) {
// 获取服务器文件大小,计算每个线程的开始位置和结束位置
URL url;
try {
url = new URL(path);
//获取HTTPURLConnection对象
HttpURLConnection connection=(HttpURLConnection)url.openConnection();
//设置Connection访问方式
connection.setRequestMethod("GET");
//设置超时时间
connection.setConnectTimeout(5000);
//获取返回的状态码
int code=connection.getResponseCode();
//判断状态码
if (code==200){
//获取服务器文件的大小
int length=connection.getContentLength();
System.out.println("length:"+length);
//创建一个大小和服务器一模一样的文件,目的是吧空间申请出来
RandomAccessFile randomAccessFile=new RandomAccessFile("dfcft8.exe", "rw");//可读可写
randomAccessFile.setLength(length);
//算出每个线程下载的大小
int blockSize=length/threadCount;
//计算每个线程下载的开始和结束位置
for (int i = 0; i < threadCount; i++) {
int startIndex=i*blockSize;//每个线程下载的开始位置
int endIndex=(i+1)*blockSize-1;
//特殊情况就是最后一个线程
if(i==threadCount-1) {
//说明是最后一个线程
endIndex=length-1;
}
System.out.println("当前线程下载的位置为:"+i+"理论下载位置为:"+startIndex+"--"+endIndex);
//开启线程去服务器下载文件
DownLoadThread downLoadThread= new DownLoadThread(startIndex, endIndex, i);
downLoadThread.start();
}
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//定义线程去服务器下载
private static class DownLoadThread extends Thread{
private int startIndex,endIndex,threadId;
//通过构造方法把每个线程的开始位置和结束位置传递过来
public DownLoadThread(int startIndex,int endIndex,int threadId) {
this.startIndex=startIndex;
this.endIndex=endIndex;
this.threadId=threadId;
}
@Override
public void run() {
// 实现去服务器下载文件的逻辑
try {
URL url = new URL(path);
//获取HTTPURLConnection对象
HttpURLConnection connection=(HttpURLConnection)url.openConnection();
//设置Connection访问方式
connection.setRequestMethod("GET");
//设置超时时间
connection.setConnectTimeout(5000);
//如果中间断过,继续上次的位置继续下载,从文件中读取上次下载的位置
File file=new File(threadId+".txt");
if (file.exists() && file.length()>0) {
FileInputStream fileInputStream=new FileInputStream(file);
BufferedReader br=new BufferedReader(new InputStreamReader(fileInputStream));
String lastPosition= br.readLine();
int lastPosi=Integer.parseInt(lastPosition);
//要改变一下startIndex的位置
startIndex=lastPosi;
System.out.println("当前线程下载的位置为:"+threadId+"真实下载位置为:"+startIndex+"--"+endIndex);
fileInputStream.close();
}
//设置一个请求头range(范围)作用是告诉服务器每个线程下载的开始位置和结束位置
connection.setRequestProperty("range", "bytes="+startIndex+"-"+endIndex);
//获取返回的状态码
int code=connection.getResponseCode();
//判断状态码
if (code==206){//206代表请求的资源成功
//创建随机读写文件对象
RandomAccessFile randomAccessFile=new RandomAccessFile("temp.txt", "rw");
//每个线程要从自己的位置写
randomAccessFile.seek(startIndex);
InputStream inputStream=connection.getInputStream();//这里connection只请求了部分资源
//把数据写到文件中
int len=-1;
byte[] buffer=new byte[1024];
//设置当前线程下载的大小(为给断点续传做准备)
int total=0;
while ((len=inputStream.read(buffer))!=-1) {
randomAccessFile.write(buffer,0,len);
total+=len;
//实现断点续传,就是把当前线程下载的位置给存起来,下次从此位置下载
int currentThreadPosition=startIndex+total;//未来将其存在一个普通的txt文本中
//用来存当前线程下载的位置
RandomAccessFile raff=new RandomAccessFile(threadId+".txt", "rwd");
raff.write(String.valueOf(currentThreadPosition).getBytes());
raff.close();
}
randomAccessFile.close();
System.out.println("线程ID:"+threadId+"----下载完毕");
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
打印:
length:57764856
当前线程下载的位置为:0理论下载位置为:0–19254951
当前线程下载的位置为:1理论下载位置为:19254952–38509903
当前线程下载的位置为:2理论下载位置为:38509904–57764855
当前线程下载的位置为:2真实下载位置为:57764856–57764855
当前线程下载的位置为:0真实下载位置为:19254952–19254951
当前线程下载的位置为:1真实下载位置为:38509904–38509903
6.断点续传,删除文件(eclipse下实现本例)
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
public class MultiDownloadMultiDownload {
//定义下载路径
private static String path="http://swdlcdn.eastmoney.com/swc8_free_new/dfcft8.exe";
//开启线程个数
private static final int threadCount=3;
//当前正在运行的线程
private static int runningThread;
public static void main(String[] args) {
// 获取服务器文件大小,计算每个线程的开始位置和结束位置
URL url;
try {
url = new URL(path);
//获取HTTPURLConnection对象
HttpURLConnection connection=(HttpURLConnection)url.openConnection();
//设置Connection访问方式
connection.setRequestMethod("GET");
//设置超时时间
connection.setConnectTimeout(5000);
//获取返回的状态码
int code=connection.getResponseCode();
//判断状态码
if (code==200){
//获取服务器文件的大小
int length=connection.getContentLength();
//把线程数量赋值给正在运行的线程
runningThread=threadCount;
System.out.println("length:"+length);
//创建一个大小和服务器一模一样的文件,目的是吧空间申请出来
RandomAccessFile randomAccessFile=new RandomAccessFile(getFileName(path), "rw");//可读可写
randomAccessFile.setLength(length);
//算出每个线程下载的大小
int blockSize=length/threadCount;
//计算每个线程下载的开始和结束位置
for (int i = 0; i < threadCount; i++) {
int startIndex=i*blockSize;//每个线程下载的开始位置
int endIndex=(i+1)*blockSize-1;
//特殊情况就是最后一个线程
if(i==threadCount-1) {
//说明是最后一个线程
endIndex=length-1;
}
System.out.println("当前线程下载的位置为:"+i+"理论下载位置为:"+startIndex+"--"+endIndex);
//开启线程去服务器下载文件
DownLoadThread downLoadThread= new DownLoadThread(startIndex, endIndex, i);
downLoadThread.start();
}
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//定义线程去服务器下载
private static class DownLoadThread extends Thread{
private int startIndex,endIndex,threadId;
//通过构造方法把每个线程的开始位置和结束位置传递过来
public DownLoadThread(int startIndex,int endIndex,int threadId) {
this.startIndex=startIndex;
this.endIndex=endIndex;
this.threadId=threadId;
}
@Override
public void run() {
// 实现去服务器下载文件的逻辑
try {
URL url = new URL(path);
//获取HTTPURLConnection对象
HttpURLConnection connection=(HttpURLConnection)url.openConnection();
//设置Connection访问方式
connection.setRequestMethod("GET");
//设置超时时间
connection.setConnectTimeout(5000);
//如果中间断过,继续上次的位置继续下载,从文件中读取上次下载的位置
File file=new File(getFileName(path)+threadId+".txt");
if (file.exists() && file.length()>0) {
FileInputStream fileInputStream=new FileInputStream(file);
BufferedReader br=new BufferedReader(new InputStreamReader(fileInputStream));
String lastPosition= br.readLine();
int lastPosi=Integer.parseInt(lastPosition);
//要改变一下startIndex的位置
startIndex=lastPosi;
System.out.println("当前线程下载的位置为:"+threadId+"真实下载位置为:"+startIndex+"--"+endIndex);
fileInputStream.close();
}
//设置一个请求头range(范围)作用是告诉服务器每个线程下载的开始位置和结束位置
connection.setRequestProperty("range", "bytes="+startIndex+"-"+endIndex);
//获取返回的状态码
int code=connection.getResponseCode();
//判断状态码
if (code==206){//206代表请求的资源成功
//创建随机读写文件对象
RandomAccessFile randomAccessFile=new RandomAccessFile(getFileName(path), "rw");
//每个线程要从自己的位置写
randomAccessFile.seek(startIndex);
InputStream inputStream=connection.getInputStream();//这里connection只请求了部分资源
//把数据写到文件中
int len=-1;
byte[] buffer=new byte[1024];
//设置当前线程下载的大小(为给断点续传做准备)
int total=0;
while ((len=inputStream.read(buffer))!=-1) {
randomAccessFile.write(buffer,0,len);
total+=len;
//实现断点续传,就是把当前线程下载的位置给存起来,下次从此位置下载
int currentThreadPosition=startIndex+total;//未来将其存在一个普通的txt文本中
//用来存当前线程下载的位置
RandomAccessFile raff=new RandomAccessFile(getFileName(path)+threadId+".txt", "rwd");
raff.write(String.valueOf(currentThreadPosition).getBytes());
raff.close();
}
randomAccessFile.close();
System.out.println("线程ID:"+threadId+"----下载完毕");
//把txt文件删除,每个线程据悉什么时候下载完毕,我们并不知道
synchronized (DownLoadThread.class) {
runningThread--;
if (runningThread==0) {
//说明所有的线程都执行完毕了,就把.txt文件删除
for (int i = 0; i < threadCount; i++) {
File deFile=new File(getFileName(path)+i+".txt");
deFile.delete();
}
}
}
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public static String getFileName(String path) {
int start =path.lastIndexOf("/")+1;
return path.substring(start);
}
}