Zookeeper写文件原子类
来源:互联网 发布:java的静态代理 编辑:程序博客网 时间:2024/06/05 12:01
文件实际是被写入一个后缀为.tmp的临时文件中,只有当数据完全写入磁盘后,才会覆盖目标文件。
在window平台下,需要先delete目标文件,再执行renameTo操作。
package org.apache.zookeeper.common;import java.io.File;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.FilterOutputStream;import java.io.IOException;import org.slf4j.Logger;import org.slf4j.LoggerFactory;/* * This code is originally from HDFS, see the similarly named files there * in case of bug fixing, history, etc... *//** * A FileOutputStream that has the property that it will only show up at its * destination once it has been entirely written and flushed to disk. While * being written, it will use a .tmp suffix. * * When the output stream is closed, it is flushed, fsynced, and will be moved * into place, overwriting any file that already exists at that location. * * <b>NOTE</b>: on Windows platforms, it will not atomically replace the target * file - instead the target file is deleted before this one is moved into * place. */public class AtomicFileOutputStream extends FilterOutputStream { private static final String TMP_EXTENSION = ".tmp"; private final static Logger LOG = LoggerFactory .getLogger(AtomicFileOutputStream.class); private final File origFile; private final File tmpFile; public AtomicFileOutputStream(File f) throws FileNotFoundException { // Code unfortunately must be duplicated below since we can't assign // anything // before calling super super(new FileOutputStream(new File(f.getParentFile(), f.getName() + TMP_EXTENSION))); origFile = f.getAbsoluteFile(); tmpFile = new File(f.getParentFile(), f.getName() + TMP_EXTENSION) .getAbsoluteFile(); } @Override public void close() throws IOException { boolean triedToClose = false, success = false; try { flush(); ((FileOutputStream) out).getChannel().force(true); triedToClose = true; super.close(); success = true; } finally { if (success) { boolean renamed = tmpFile.renameTo(origFile); if (!renamed) { // On windows, renameTo does not replace. if (!origFile.delete() || !tmpFile.renameTo(origFile)) { throw new IOException( "Could not rename temporary file " + tmpFile + " to " + origFile); } } } else { if (!triedToClose) { // If we failed when flushing, try to close it to not leak // an FD IOUtils.closeStream(out); } // close wasn't successful, try to delete the tmp file if (!tmpFile.delete()) { LOG.warn("Unable to delete tmp file " + tmpFile); } } } } /** * Close the atomic file, but do not "commit" the temporary file on top of * the destination. This should be used if there is a failure in writing. */ public void abort() { try { super.close(); } catch (IOException ioe) { LOG.warn("Unable to abort file " + tmpFile, ioe); } if (!tmpFile.delete()) { LOG.warn("Unable to delete tmp file during abort " + tmpFile); } }}在QuorumPeer类中,将一个long值写入磁盘时,用到了此类,要么写入成功要么抛出异常:
private void writeLongToFile(String name, long value) throws IOException { File file = new File(logFactory.getSnapDir(), name); AtomicFileOutputStream out = new AtomicFileOutputStream(file); BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(out)); boolean aborted = false; try { bw.write(Long.toString(value)); bw.flush(); out.flush(); } catch (IOException e) { LOG.error("Failed to write new file " + file, e); aborted = true; out.abort(); throw e; } finally { if (!aborted) { out.close(); } } }
0 0
- Zookeeper写文件原子类
- 原子类
- Java写文件不覆盖原内容
- 原子类 与 volatile
- java原子类---笔记
- JUC 原子类
- AtomicReference原子类
- java中的原子类
- Java中的原子类
- java多线程--原子类
- Java原子类
- 原子类 与 volatile
- Java 并发:原子类
- AtomicReference原子类
- 多线程--原子类理解
- java 多线程 原子类
- AtomicReference原子类
- AtomicReference原子类
- block使用小结、在arc中使用block、如何防止循环引用
- postgre常用系统函数
- 14. Linux下的用户管理
- 小黑小波比.随机班号
- Android ActionBar完全解析,使用官方推荐的最佳导航栏(下)
- Zookeeper写文件原子类
- 数据结构-链队列
- 蓝桥杯备战-阶乘计算
- 程序开发的一些思考
- js取年月最后一天
- Android抽象布局——include、merge 、ViewStub
- 删除项目中文件夹下包含的 .svn .git CVS等等遗留文件
- AnnotationAwareAspectJAutoProxyCreator is only available on Java 1.5 and higher
- PP(1) 基本流程