转载: https://www.cnblogs.com/byrhuangqiang/p/3924985.html
今天在编写hadoop程序的时候,用到了流的处理。关闭流的时候出现了问题:
代码:
1 FSDataInputStream fsin = fs.open(new Path(filein)); 2 FSDataOutputStream fsout = fs.append(new Path(fileout)); 3 BufferedReader br = new BufferedReader(new InputStreamReader(fsin)); 4 BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(fsout)); 5 ... 6 br.close(); 7 fsin.close(); 8 bw.close(); 9 fsout.close();
异常:
1 [root@bigdata004 bigdata]# ./bigdataTimer.sh 2 INFO [main] com.sinosoft.bigdata.BigDataTimer.main(227) | -----Timer begin----- 3 INFO [main] com.sinosoft.bigdata.BigDataInit.(70) | bigdata init ... 4 WARN [main] org.apache.hadoop.util.NativeCodeLoader. (62) | Unable to load native-hadoop library for your platform... using builtin-java classes where applicable 5 INFO [main] com.sinosoft.bigdata.BigDataTimer.mergeFile(66) | Finished appending file. 6 INFO [main] com.sinosoft.bigdata.BigDataTimer.mergeFile(68) | deleted the input data path. 7 INFO [main] com.sinosoft.bigdata.BigDataTimer.mergeFile(70) | create the input data path. 8 ERROR [main] org.apache.hadoop.hdfs.DFSClient.closeAllFilesBeingWritten(776) | Failed to close file /user/root/dayfileInput/dayfileIn 9 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();最后抛出了异常。
回顾了一下流的知识:
按照流是否直接与特定的地方(如磁盘、内存、设备等)相连,分为节点流和处理流两类。
JAVA常用的节点流:
常用处理流(关闭处理流使用关闭里面的节点流)
---增加缓冲功能,避免频繁读写硬盘。
注意:
另一篇:
https://www.cnblogs.com/tongxuping/p/8192073.html
1.在finally中关闭流;
OutputStream out = null; try { out = new FileOutputStream(""); // ...操作流代码 } catch (Exception e) { e.printStackTrace(); } finally { try { if (out != null) { out.close(); } } catch (Exception e) { e.printStackTrace(); } }
2.在关闭多个流时因为嫌麻烦将所有关流的代码丢到一个try中
OutputStream out = null; OutputStream out2 = null; try { out = new FileOutputStream(""); out2 = new FileOutputStream(""); // ...操作流代码 } catch (Exception e) { e.printStackTrace(); } finally { try { if (out != null) { out.close();// 如果此处出现异常,则out2流也会被关闭 } } catch (Exception e) { e.printStackTrace(); } try { if (out2 != null) { out2.close(); } } catch (Exception e) { e.printStackTrace(); } }
3.在循环中创建流,在循环外关闭,导致关闭的是最后一个流
for (int i = 0; i < 10; i++) { OutputStream out = null; try { out = new FileOutputStream(""); // ...操作流代码 } catch (Exception e) { e.printStackTrace(); } finally { try { if (out != null) { out.close(); } } catch (Exception e) { e.printStackTrace(); } } }
4.在Java7中,关闭流这种繁琐的操作就不用我们自己写了
只要实现的自动关闭接口(Closeable)的类都可以在try结构体上定义,java会自动帮我们关闭,及时在发生异常的情况下也会。可以在try结构体上定义多个,用分号隔开即可,如:
try (OutputStream out = new FileOutputStream("");OutputStream out2 = new FileOutputStream("")){ // ...操作流代码 } catch (Exception e) { throw e; }