關於檔案讀寫,執行緒超時終止問題
在對網路檔案下載進行讀寫操作時,有時候會因為網路問題導致 “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