代碼:
FSDataInputStream fsin = fs.open(new Path(filein));
FSDataOutputStream fsout = fs.append(new Path(fileout));
BufferedReader br = new BufferedReader(new InputStreamReader(fsin));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(fsout));
br.close();
fsin.close();
bw.close();
fsout.close();
異常:
[root@bigdata004 bigdata]# ./bigdataTimer.sh
INFO [main] com.sinosoft.bigdata.BigDataTimer.main(227) | -----Timer begin-----
INFO [main] com.sinosoft.bigdata.BigDataInit.(70) | bigdata init ...
WARN [main] org.apache.hadoop.util.NativeCodeLoader.(62) | Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
INFO [main] com.sinosoft.bigdata.BigDataTimer.mergeFile(66) | Finished appending file.
INFO [main] com.sinosoft.bigdata.BigDataTimer.mergeFile(68) | deleted the input data path.
INFO [main] com.sinosoft.bigdata.BigDataTimer.mergeFile(70) | create the input data path.
ERROR [main] org.apache.hadoop.hdfs.DFSClient.closeAllFilesBeingWritten(776) | Failed to close file /user/root/dayfileInput/dayfileIn
org.apache.hadoop.ipc.RemoteException(org.apache.hadoop.hdfs.server.namenode.LeaseExpiredException): No lease on /user/root/dayfileInput/dayfileIn: File does not exist. Holder DFSClient_NONMAPREDUCE_-221972347_1 does not have any open files.
原因:關閉處理流br.close();之后,緊接着關閉了與之相關的fsin.close();的節點流。事實上,br.close();會調用fsin.close(); 因此重復關閉了2次fsin.close();最后拋出了異常。
回顧了一下流的知識:
(1)按照流是否直接與特定的地方(如磁盤、內存、設備等)相連,分為節點流和處理流兩類。
節點流:可以從或向一個特定的地方(節點)讀寫數據。如FileReader.
處理流:是對一個已存在的流的連接和封裝,通過所封裝的流的功能調用實現數據讀寫。如BufferedReader.處理流的構造方法總是要帶一個其他的流對象做參數。一個流對象經過其他流的多次包裝,稱為流的鏈接。
(2)JAVA常用的節點流:
文 件 FileInputStream FileOutputStrean FileReader FileWriter 文件進行處理的節點流。
字符串 StringReader StringWriter 對字符串進行處理的節點流。
數 組 ByteArrayInputStream ByteArrayOutputStreamCharArrayReader CharArrayWriter 對數組進行處理的節點流(對應的不再是文件,而是內存中的一個數組)。
管 道 PipedInputStream PipedOutputStream PipedReaderPipedWriter對管道進行處理的節點流。
(3)常用處理流(關閉處理流使用關閉里面的節點流)
緩沖流:BufferedInputStrean BufferedOutputStream BufferedReader BufferedWriter —增加緩沖功能,避免頻繁讀寫硬盤。
轉換流:InputStreamReader OutputStreamReader實現字節流和字符流之間的轉換。
數據流 DataInputStream DataOutputStream 等-提供將基礎數據類型寫入到文件中,或者讀取出來.
流的關閉順序
-一般情況下是:先打開的后關閉,后打開的先關閉。
-另一種情況:看依賴關系,如果流a依賴流b,應該先關閉流a,再關閉流b。例如,處理流a依賴節點流b,應該先關閉處理流a,再關閉節點流b。
可以只關閉處理流,不用關閉節點流。處理流關閉的時候,會調用其處理的節點流的關閉方法。
注意:
-如果將節點流關閉以后再關閉處理流,會拋出IO異常。
-如果關閉了處理流,在關閉與之相關的節點流,也可能出現IO異常。(hadoop編程文件流操作中遇到了。)