Java IO和网络编程

作者:陆金龙    发表时间:2024-02-24 05:44   

关键词:  

17.2.1 使用InetAddress


// 根据主机名来获取对应的InetAddress实例
InetAddress ip = InetAddress.getByName("www.crazyit.org");
// 判断是否可达
System.out.println("crazyit是否可达:" + ip.isReachable(2000));
// 获取该InetAddress实例的IP字符串
System.out.println(ip.getHostAddress());
// 根据原始IP地址来获取对应的InetAddress实例
InetAddress local = InetAddress.getByAddress(new byte[]{127,0,0,1});
System.out.println("本机是否可达:" + local.isReachable(5000));
// 获取该InetAddress实例对应的全限定域名
System.out.println(local.getCanonicalHostName());

17.2.2 使用URLEncoderURLDecoder
// application/x-www-form-urlencoded字符串转换成普通字符串
String keyWord = URLDecoder.decode("%E7%96%AF%E7%8B%82java", "utf-8");
System.out.println(keyWord);

// 将普通字符串转换成 application/x-www-form-urlencoded字符串
String urlStr = URLEncoder.encode("疯狂Android讲义" , "GBK");
System.out.println(urlStr);


17.2.3 URLURLConnectionURLPermission 多线程下载

public class DownUtil
{
    // 定义下载资源的路径
    private String path;
    // 指定所下载的文件的保存位置
    private String targetFile;
    // 定义需要使用多少线程下载资源
    private int threadNum;
    // 定义下载的线程对象
    private DownThread[] threads;
    // 定义下载的文件的总大小
    private int fileSize;

    public DownUtil(String path, String targetFile, int threadNum)
{
    this.path = path;
    this.threadNum = threadNum;
    // 初始化threads数组
    threads = new DownThread[threadNum];
    this.targetFile = targetFile;
}

public void download() throws Exception
{
    URL url = new URL(path);
    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
    conn.setConnectTimeout(5 * 1000);
    conn.setRequestMethod("GET");
    conn.setRequestProperty(
        "Accept",
        "image/gif, image/jpeg, image/pjpeg, image/pjpeg, "
        + "application/x-shockwave-flash, application/xaml+xml, "
        + "application/vnd.ms-xpsdocument, application/x-ms-xbap, "
        + "application/x-ms-application, application/vnd.ms-excel, "
        + "application/vnd.ms-powerpoint, application/msword, */*");
    conn.setRequestProperty("Accept-Language", "zh-CN");
    conn.setRequestProperty("Charset", "UTF-8");
    conn.setRequestProperty("Connection", "Keep-Alive");
    // 得到文件大小
    fileSize = conn.getContentLength();
    conn.disconnect();
    int currentPartSize = fileSize / threadNum + 1;
    RandomAccessFile file = new RandomAccessFile(targetFile, "rw");
    // 设置本地文件的大小
    file.setLength(fileSize);
    file.close();
    for (int i = 0; i < threadNum; i++)
    {
        // 计算每条线程的下载的开始位置
        int startPos = i * currentPartSize;
        // 每个线程使用一个RandomAccessFile进行下载
        RandomAccessFile currentPart = new RandomAccessFile(targetFile,"rw");
        // 定位该线程的下载位置
        currentPart.seek(startPos);
        // 创建下载线程
        threads[i] = new DownThread(startPos, currentPartSize,currentPart);
        // 启动下载线程
        threads[i].start();
    }
}

// 获取下载的完成百分比
public double getCompleteRate()
{
    // 统计多条线程已经下载的总大小
    int sumSize = 0;
    for (int i = 0; i < threadNum; i++)
    {
        sumSize += threads[i].length;
    }
    // 返回已经完成的百分比
    return sumSize * 1.0 / fileSize;
}

private class DownThread extends Thread
{
    // 当前线程的下载位置
    private int startPos;
    // 定义当前线程负责下载的文件大小
    private int currentPartSize;
    // 当前线程需要下载的文件块
    private RandomAccessFile currentPart;
    // 定义已经该线程已下载的字节数
    public int length;

    public DownThread(int startPos, int currentPartSize,
    RandomAccessFile currentPart)
{
    this.startPos = startPos;
    this.currentPartSize = currentPartSize;
    this.currentPart = currentPart;
}

@Override
public void run()
{
    try
    {
        URL url = new URL(path);
        HttpURLConnection conn = (HttpURLConnection)url
        .openConnection();
        conn.setConnectTimeout(5 * 1000);
        conn.setRequestMethod("GET");
        conn.setRequestProperty(
            "Accept",
            "image/gif, image/jpeg, image/pjpeg, image/pjpeg, "
            + "application/x-shockwave-flash, application/xaml+xml, "
            + "application/vnd.ms-xpsdocument, application/x-ms-xbap, "
            + "application/x-ms-application, application/vnd.ms-excel, "
            + "application/vnd.ms-powerpoint, application/msword, */*");
        conn.setRequestProperty("Accept-Language", "zh-CN");
        conn.setRequestProperty("Charset", "UTF-8");
        InputStream inStream = conn.getInputStream();
        // 跳过startPos个字节,表明该线程只下载自己负责哪部分文件。
        inStream.skip(this.startPos);

        byte[] buffer = new byte[1024];
        int hasRead = 0;
        // 读取网络数据,并写入本地文件
        while (length < currentPartSize
        && (hasRead = inStream.read(buffer)) != -1)
        {
            currentPart.write(buffer, 0, hasRead);
            // 累计该线程下载的总大小
            length += hasRead;
        }
        currentPart.close();
        inStream.close();
    }
    catch (Exception e)
    {
        e.printStackTrace();
    }
}
}
}

public static void main(String[] args) throws Exception
{
    // 初始化DownUtil对象
    final DownUtil downUtil = new DownUtil("http://www.crazyit.org/"
    + "attachments/month_1403/1403202355ff6cc9a4fbf6f14a.png"
    , "ios.png", 4);
    // 开始下载
    downUtil.download();
    new Thread(() -> {
        while(downUtil.getCompleteRate() < 1)
        {
            // 每隔0.1秒查询一次任务的完成进度,
            // GUI程序中可根据该进度来绘制进度条
            System.out.println("已完成:"+ downUtil.getCompleteRate());
            try
            {
                Thread.sleep(1000);
            }
            catch (Exception ex){}
        }
    }).start();
}



17.2.4 Http Get和Post请求



public class GetPostTest
{
    /**
     * 向指定URL发送GET方法的请求
     * @param url 发送请求的URL
     * @param param 请求参数,格式满足name1=value1&name2=value2的形式。
     * @return URL所代表远程资源的响应
     */
    public static String sendGet(String url , String param)
{
    String result = "";
    String urlName = url + "?" + param;
    try
{
    URL realUrl = new URL(urlName);
    // 打开和URL之间的连接
    URLConnection conn = realUrl.openConnection();
    // 设置通用的请求属性
    conn.setRequestProperty("accept", "*/*");
    conn.setRequestProperty("connection", "Keep-Alive");
    conn.setRequestProperty("user-agent"
, "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");
    // 建立实际的连接
    conn.connect();
    // 获取所有响应头字段
    Map<String, List<String>> map = conn.getHeaderFields();
    // 遍历所有的响应头字段
    for (String key : map.keySet())
{
    System.out.println(key + "--->" + map.get(key));
}
try(
    // 定义BufferedReader输入流来读取URL的响应
    BufferedReader in = new BufferedReader(
        new InputStreamReader(conn.getInputStream() , "utf-8")))
{
    String line;
    while ((line = in.readLine())!= null)
    {
        result += "\n" + line;
    }
}
}
catch(Exception e)
{
    System.out.println("发送GET请求出现异常!" + e);
    e.printStackTrace();
}
return result;
}
/**
 * 向指定URL发送POST方法的请求
 * @param url 发送请求的URL
 * @param param 请求参数,格式应该满足name1=value1&name2=value2的形式。
 * @return URL所代表远程资源的响应
 */
public static String sendPost(String url , String param)
{
    String result = "";
    try
    {
        URL realUrl = new URL(url);
        // 打开和URL之间的连接
        URLConnection conn = realUrl.openConnection();
        // 设置通用的请求属性
        conn.setRequestProperty("accept", "*/*");
        conn.setRequestProperty("connection", "Keep-Alive");
        conn.setRequestProperty("user-agent",
            "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");
        // 发送POST请求必须设置如下两行
        conn.setDoOutput(true);
        conn.setDoInput(true);
        try(
        // 获取URLConnection对象对应的输出流
        PrintWriter out = new PrintWriter(conn.getOutputStream()))
        {
            // 发送请求参数
            out.print(param);
            // flush输出流的缓冲
            out.flush();
        }
        try(
        // 定义BufferedReader输入流来读取URL的响应
        BufferedReader in = new BufferedReader(new InputStreamReader
        (conn.getInputStream() , "utf-8")))
        {
            String line;
            while ((line = in.readLine())!= null)
            {
                result += "\n" + line;
            }
        }
    }
    catch(Exception e)
    {
        System.out.println("发送POST请求出现异常!" + e);
        e.printStackTrace();
    }
    return result;
}
// 提供主方法,测试发送GET请求和POST请求
public static void main(String args[])
{
    // 发送GET请求
    String s = GetPostTest.sendGet("http://localhost:8888/abc/a.jsp"
    , null);
    System.out.println(s);
    // 发送POST请求
    String s1 = GetPostTest.sendPost("http://localhost:8888/abc/login.jsp"
    , "name=crazyit.org&pass=leegang");
    System.out.println(s1);
}
}