1. 程式人生 > >關於檔案讀寫,執行緒超時終止問題

關於檔案讀寫,執行緒超時終止問題

在對網路檔案下載進行讀寫操作時,有時候會因為網路問題導致 “Connection reset” 異常以及有時會在一半的時候卡住,針對這個兩種情況需要重新去下載,第一種異常比較好判斷,可以直接拿錯誤資訊即可判斷,第二種情況想到的辦法就是利用執行緒去解決,給下載單獨開啟一個子執行緒,並且給該子執行緒設定一個超時時間,當超過改時間時,則取消下載,中斷該子執行緒!

在這裡通過實現Callable介面類來設定超時任務:

package com.java.mytest;

import com.csvreader.CsvReader;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;

import java.io.*;
import java.net.MalformedURLException;
import java.net.SocketException;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.*;

/**
 * @Author win7
 * @Date 12/1/16 2:45 PM
 */
public class TestDownloadFile {
    private static String tempUrl = "http://xxxx/test.txt";
    private static String filePath;

    public static void main(String[] args) {
        String suffixName = tempUrl.substring(tempUrl.lastIndexOf("/") + 1, tempUrl.length());
        int timeout = 20; //秒.
        int num = 1;
        Boolean flag = null;
        while (true) {
            ExecutorService executor = Executors.newSingleThreadExecutor();
            Boolean result = false;
            DownloadFile downloadFile = new DownloadFile(suffixName, num);
            Future<Boolean> future = executor.submit(downloadFile);// 將任務提交到執行緒池中
            try {
                future.get(timeout, TimeUnit.SECONDS);// 設定在20秒的時間內完成
            } catch (InterruptedException e) {
                filePath = null;
                System.out.println("執行緒中斷出錯--------"+num);
            } catch (ExecutionException e) {
                filePath = null;
                System.out.println("執行緒服務出錯--------"+num);
            } catch (TimeoutException e) {// 超時異常
                filePath = "Connection reset";
                System.out.println("執行緒服務超時--------"+num);
            } finally {
		
//關閉此下載任務downloadFile.setIsStop(true); flag = future.cancel(true);// 中斷執行此任務的執行緒 System.out.println("執行緒服務關閉--------"+num); System.out.println("result is " + result); System.out.println("刪除結果:" + flag); executor.shutdownNow();//關閉ExecutorService,阻止等待任務啟動並試圖停止當前正在執行的任務 //超過3次終止整個任務 if (num >= 3){ break; } } if (StringUtils.isBlank(filePath)){ System.out.println("download file is error!"); break; }else { if ("Connection reset".equalsIgnoreCase(filePath)){ System.out.println("============Connection reset continue==========="+num); num++; continue; }else { File file = new File(filePath); if (file.exists()){ System.out.println("============SUCCESS==========="+num); break; }else { System.out.println("============"+filePath+" continue==========="+num); continue; } } } } } static class DownloadFile implements Callable<Boolean> { private String fileName; private int num; //是否關閉此下載任務 private boolean isStop = false; public DownloadFile(String suffixName, int num) { this.fileName = suffixName; this.num = num; } /** * 將檔案下載到本地 */ @Override public Boolean call(){ filePath = "F:/" + fileName; URL url = null; URLConnection conn = null; try { url = new URL(tempUrl); conn = url.openConnection(); } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } if (null == url || null == conn){ filePath = null; return false; } try ( //try語句結束後自動關閉資源 InputStream inputStream = conn.getInputStream(); FileOutputStream outputStream = new FileOutputStream(filePath) ) { byte[] buffer = new byte[1204]; int length; while ((length = inputStream.read(buffer)) != -1) {
if (isStop){ break; } outputStream.write(buffer, 0, length); } }catch (Exception e){ filePath = e.getMessage(); e.printStackTrace(); }finally { File file = new File(filePath); if (file.exists()){ return true; } return false; } } public void setIsStop(boolean isStop) { this.isStop = isStop; } } }
記錄下上面程式碼遇到的坑:

如果任務超時了,從而執行了future.cancel(true)以及executor.shutdownNow()此時這個執行緒就應該終結,但是實際上由於用到了IO讀寫操作,並且是阻塞式的,所以這個執行緒並沒有終止而是繼續的存在的,要知道jvm只有在所有(非守護)執行緒推出後才會退出,所以此時的jvm並沒有因為方法執行完畢而退出。

解決辦法:

1、是在讀寫的時候加上一個是否停止的標識

2、將阻塞式的IO讀寫操作換成不阻塞的NIO讀寫操作(此方法沒去測試,待下次有時間在測)

相關推薦

關於檔案執行超時終止問題

在對網路檔案下載進行讀寫操作時,有時候會因為網路問題導致 “Connection reset” 異常以及有時會在一半的時候卡住,針對這個兩種情況需要重新去下載,第一種異常比較好判斷,可以直接拿錯誤資訊即可判斷,第二種情況想到的辦法就是利用執行緒去解決,給下載單獨開啟一個子執

java檔案

/**  *   */ package com.struts2.other; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.F

學習筆記四 檔案集合元組函式

一、檔案讀寫幾種模式總結: 讀模式: r 開啟不存在的檔案會報錯、不能寫(不能呼叫write方法),可以讀(能呼叫read方法) 寫模式: w # 1、開啟不存在的檔案,會新建一個檔案,但每次開啟都會清空原有檔案內容       # 2、不能讀(不能呼叫read方法),可以寫(能呼叫write方法)

檔案函式元組和集合

1、檔案讀寫 f = open('day4','r+',encoding = 'utf-8') #讀模式 r 開啟不存在的檔案會報錯、只能讀、不能寫 #寫模式 w #1、開啟不存在的檔案,會新建一個檔案,會清空原有檔案 #2、不

android檔案ndk檔案

                1 android檔案讀寫相關文章 http://sunzone.iteye.com/blog

設計一個執行超時終止執行

起因是公司有一個定時任務,對於幾千的VPN,做一個埠對映,去取得對方客戶的硬體資訊,做一個監控。 但是部分VPN會連線不通,等待的時間又過長,所以設計這麼一個執行緒池。 原貼提供了一個執行緒超時終止的實現方式,我再在這個基礎上,整理成一個執行緒池。 首先是執行緒超時終

CMD:從檔案執行後輸出至另一檔案

CMD:從文件讀入,執行後輸出至另一文件 作者在介紹前的吐槽:為什麼NOIP等比賽必須開freopen!浪費精力,語句還容易錯! 廢話少,馬上入正文 1.向檔案輸出 程式碼框架 [命令]>>[檔名] 例如:chkdsk /f >>D:\o

關於properties配置檔案追加以及中文亂碼問題

在開發中常用properties檔案來儲存系統配置資訊,下面就properties檔案的讀寫,資訊追加作簡要介紹,順便也解決亂碼問題。 1、首先介紹一下properties類 properties類繼承自Hashtable package com.gmi.

C++ 獲取某檔案的大小(位元組數)(大檔案支援大於2GB檔案

一個檔案的大小可能大於1GB , 用 __int64 來表示其大小. #include <stdlib.h> #include <string.h> #include<stdio.h> #include "io.h" __int64 fi

python 檔案刪除指定行

# -*- coding:utf-8 -*- import re import os import random d1 = {} """ 寫檔案""" files = open('test.txt','a+') strs = "世界很大" for var in range(

實驗6  檔案與多執行

1基礎知識 檔案與檔案路徑 檔案有兩個關鍵屬性:檔名和路徑。檔名中的最後一個句點之後的部分被稱為檔案的“副檔名”,它指明瞭檔案的型別。路徑指明瞭檔案在計算機上的位置。在Windows中,路徑書寫使用倒斜槓(\)作為資料夾之間的分隔符,而OS X和Linux中,則使用正

JAVA基礎24-多執行(四)【阻塞佇列執行池】

一、讀寫鎖   使用步驟 二、阻塞佇列 (BlockingQueue) 提供執行緒安全的佇列訪問方式; 當阻塞佇列進行插入資料時,若佇列滿,則執行緒阻塞,直到佇列非滿的時候 當阻塞佇列取資料時,若佇列為空,則執行緒阻塞直到佇列非空時候。

Python多執行同步---檔案控制

1、實現檔案讀寫的檔案ltz_schedule_times.py #! /usr/bin/env python #coding=utf-8 import os def ReadTimes():

使用執行同時讀取兩個檔案執行相關問題

使用執行緒同時讀取兩個檔案並寫出 1,建立工具類(載入檔案,讀取內容,寫出內容等方法) reader = new BufferedReader(new Reader(new File(file)); 檔案會有中文亂碼, reader = new BufferedRea

執行基礎二(執行的啟動、終止執行面臨的三種問題)

一、執行緒的啟動、終止方式   啟動: start native(呼叫外部介面啟動)     終止:    stop(類似kill,暴力終止)  interrupt 中斷的方式 通過指令的方式 volatile boolean stop

Android使用chmod改變安卓專案下檔案執行的許可權

最初我們可以看到private.txt檔案 當前使用者具有可讀可寫許可權,當前使用者所在組具有可讀可寫許可權,其他使用者沒有任何許可權,下面我們就要利用chmod指令對private.txt許可權進行修改。 首先用開始按鈕+R開啟執行,輸入cmd進入終端頁面,輸入adb shell回車,然

改進的中科院分詞系統NLPIR程式碼(加入使用者詞典去停用詞檔案)+情感分析字典包+工具包+論文包

NLPIR分詞,加入使用者詞典,去停用詞,檔案讀寫等 原始碼下載地址 優化的分詞系統程式碼 原始碼下載地址 NLPIR分詞系統 優化的分詞系統程式碼 以下是核心程式碼 完整程式碼可以直接執行分詞,點我跳轉 public cl

檔案的定位檔案的相關操作

什麼是定位? <1>獲取當前讀寫的位置 在讀寫檔案的過程中,如果想知道當前的位置,可以使用tell()來獲取 # 開啟一個已經存在的檔案 f = open("test.txt", "r") str = f.read(3) print "讀取的資料是 : ",

Qt 檔案將讀取的資料儲存到Qvector

#include "mainwindow.h" #include "ui_mainwindow.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) {

java大檔案操作java nio 之MappedByteBuffer高效檔案/記憶體對映

原文地址:https://www.cnblogs.com/lyftest/p/6564282.html   java處理大檔案,一般用BufferedReader,BufferedInputStream這類帶緩衝的Io類,不過如果檔案超大的話,更快的方式是採用MappedByteB