Esempio n. 1
0
 /**
  * 检查文件是否上锁
  *
  * @return
  * @throws IOException
  */
 public boolean validateFile() throws IOException {
   fileUrl = System.getProperty("user.dir") + "/SpiderRun.lock";
   File myfilelock = new File(fileUrl);
   RandomAccessFile raf = null;
   FileChannel fc = null;
   if (!myfilelock.exists()) {
     // 不存在,则新增文件,然后加锁
     raf = new RandomAccessFile(myfilelock, "rw");
     fc = raf.getChannel();
     FileLock fl = fc.tryLock();
     if (fl != null && fl.isValid()) {
       //                System.err.println(fileUrl + "文件被创建且被锁!");
       return false;
     }
   } else {
     // 存在,判断是否被锁
     raf = new RandomAccessFile(myfilelock, "rw");
     fc = raf.getChannel();
     FileLock fl = fc.tryLock();
     if (fl != null && fl.isValid()) {
       // 被锁
       System.err.println(fileUrl + "文件已被锁,请删除后,再启动该进程!");
       return true;
     }
   }
   return false;
 }
Esempio n. 2
0
  @Test
  public void testLockNegative() throws IOException {
    FileChannel channel = channel(regularFile(0), READ, WRITE);

    try {
      channel.lock(-1, 10, true);
      fail();
    } catch (IllegalArgumentException expected) {
    }

    try {
      channel.lock(0, -1, true);
      fail();
    } catch (IllegalArgumentException expected) {
    }

    try {
      channel.tryLock(-1, 10, true);
      fail();
    } catch (IllegalArgumentException expected) {
    }

    try {
      channel.tryLock(0, -1, true);
      fail();
    } catch (IllegalArgumentException expected) {
    }
  }
Esempio n. 3
0
 /**
  * Try to open the file.
  *
  * @param fileName the file name
  * @param readOnly whether the file should only be opened in read-only mode, even if the file is
  *     writable
  * @param encryptionKey the encryption key, or null if encryption is not used
  */
 public void open(String fileName, boolean readOnly, char[] encryptionKey) {
   if (file != null) {
     return;
   }
   if (fileName != null) {
     FilePath p = FilePath.get(fileName);
     // if no explicit scheme was specified, NIO is used
     if (p instanceof FilePathDisk && !fileName.startsWith(p.getScheme() + ":")) {
       // ensure the NIO file system is registered
       FilePathNio.class.getName();
       fileName = "nio:" + fileName;
     }
   }
   this.fileName = fileName;
   FilePath f = FilePath.get(fileName);
   FilePath parent = f.getParent();
   if (parent != null && !parent.exists()) {
     throw DataUtils.newIllegalArgumentException("Directory does not exist: {0}", parent);
   }
   if (f.exists() && !f.canWrite()) {
     readOnly = true;
   }
   this.readOnly = readOnly;
   try {
     file = f.open(readOnly ? "r" : "rw");
     if (encryptionKey != null) {
       byte[] key = FilePathEncrypt.getPasswordBytes(encryptionKey);
       encryptedFile = file;
       file = new FilePathEncrypt.FileEncrypt(fileName, key, file);
     }
     file = FilePathCache.wrap(file);
     try {
       if (readOnly) {
         fileLock = file.tryLock(0, Long.MAX_VALUE, true);
       } else {
         fileLock = file.tryLock();
       }
     } catch (OverlappingFileLockException e) {
       throw DataUtils.newIllegalStateException(
           DataUtils.ERROR_FILE_LOCKED, "The file is locked: {0}", fileName, e);
     }
     if (fileLock == null) {
       throw DataUtils.newIllegalStateException(
           DataUtils.ERROR_FILE_LOCKED, "The file is locked: {0}", fileName);
     }
     fileSize = file.size();
   } catch (IOException e) {
     throw DataUtils.newIllegalStateException(
         DataUtils.ERROR_READING_FAILED, "Could not open file {0}", fileName, e);
   }
 }
  private boolean lock(int flg) {

    try {
      if (fc != null) {
        if (flg == TRY_LOCK_FLG) {
          fl = fc.tryLock();
        } else if (flg == LOCK_FLG) {
          fl = fc.lock();
        }
        if (fl == null) {
          return false;
        }
        return true;
      } else {
        return false;
      }
    } catch (IOException e) {
      e.printStackTrace();
      try {
        fl.release();
      } catch (IOException ex) {
        ex.printStackTrace();
      }
      return false;
    }
  }
Esempio n. 5
0
  public boolean isLocked() {
    try {
      channel = new RandomAccessFile(file, "rw").getChannel();
      try {
        lock = channel.tryLock();
      } catch (OverlappingFileLockException e) {
        close();
        return true;
      }

      if (lock == null) {
        close();
        return true;
      }

      hook =
          new Thread() {
            @Override
            public void run() {
              close();
              deleteFile();
            }
          };
      Runtime.getRuntime().addShutdownHook(hook);
      return false;
    } catch (Exception e) {
      close();
      return true;
    }
  }
  public static boolean isAppActive() {
    try {
      file = new File(System.getProperty("user.home"), appName + ".tmp");
      channel = new RandomAccessFile(file, "rw").getChannel();

      try {
        lock = channel.tryLock();
      } catch (OverlappingFileLockException e) {
        // already locked
        closeLock();
        return true;
      }

      if (lock == null) {
        closeLock();
        return true;
      }

      Runtime.getRuntime()
          .addShutdownHook(
              new Thread() {
                // destroy the lock when the JVM is closing
                public void run() {
                  closeLock();
                  deleteFile();
                }
              });
      return false;
    } catch (Exception e) {
      closeLock();
      return true;
    }
  }
Esempio n. 7
0
 public StorageRootFile(String dbPath, String options, int pageSize, FreeSpaceManager fsm) {
   this.fsm = fsm;
   PAGE_SIZE = pageSize;
   File file = new File(dbPath);
   if (!file.exists()) {
     throw DBLogger.newUser("DB file does not exist: " + dbPath);
   }
   try {
     raf = new RandomAccessFile(file, options);
     fc = raf.getChannel();
     try {
       // tryLock is supposed to return null, but it throws an Exception
       fileLock = fc.tryLock();
       if (fileLock == null) {
         fc.close();
         raf.close();
         throw DBLogger.newUser("This file is in use by another process: " + dbPath);
       }
     } catch (OverlappingFileLockException e) {
       fc.close();
       raf.close();
       throw DBLogger.newUser("This file is in use by another PersistenceManager: " + dbPath);
     }
     if (ZooDebug.isTesting()) {
       ZooDebug.registerFile(fc);
     }
   } catch (IOException e) {
     throw DBLogger.newFatal("Error opening database: " + dbPath, e);
   }
 }
Esempio n. 8
0
 public OneInstanceGuard(String lockFileName) {
   lockFile = new File(lockFileName);
   if (lockFile.exists()) {
     lockFile.delete();
   }
   try {
     channel = new RandomAccessFile(lockFile, "rw").getChannel();
   } catch (FileNotFoundException e) {
     // Not running
     LOG.info("File not found: " + e);
     return;
   }
   try {
     lock = channel.tryLock();
     if (lock == null) {
       // File is lock by other application
       channel.close();
       throw new IOException("Instance already active");
     }
   } catch (IOException e) {
     // Running
     LOG.info("Instance already running");
     alreadyRunning = true;
     return;
   }
   ShutdownHook shutdownHook = new ShutdownHook(this);
   Runtime.getRuntime().addShutdownHook(shutdownHook);
 }
Esempio n. 9
0
  /** Reply a specific WAL. */
  private void replayLog(Path logPath) throws KevaDBException {
    // Now look at the disk.
    if (logPath != null) {
      // Get a list of the sstables already in place.
      Map<String, Integer> manifest =
          db.getDiskService().getDataManifests(db, 0, SSTableService.MAX_LEVELS);

      FileLock fileLock = null;
      try {
        // Must open in "rw" mode so that we can use filelock.
        FileChannel fc =
            FileChannel.open(logPath, StandardOpenOption.READ, StandardOpenOption.WRITE);
        MappedByteBuffer in = fc.map(FileChannel.MapMode.READ_ONLY, 0, (int) fc.size());

        fileLock = fc.tryLock();
        if (fileLock != null) {
          for (; ; ) {
            if (!unroll(in, manifest)) {
              break;
            }
          }
        }

        if (fileLock != null) {
          fileLock.release();
        }

        fc.close();
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
  }
  /**
   * @param directory
   * @return
   * @throws IOException
   */
  FileLock acquireLock(File directory) throws IOException {
    // Get a file channel for the file
    File file = new File(directory, LOCK_FILE);
    FileChannel channel = new RandomAccessFile(file, "rw").getChannel();

    // Use the file channel to create a lock on the file.
    // This method blocks until it can retrieve the lock.
    FileLock lock = channel.lock();

    // Try acquiring the lock without blocking. This method returns
    // null or throws an exception if the file is already locked.
    while (!lock.isValid()) {
      try {
        lock = channel.tryLock();
      } catch (OverlappingFileLockException e) {
        // File is already locked in this thread or virtual machine
      }
      // wait for the other process to unlock it, should take a couple of seconds
      try {
        Thread.sleep(500);
      } catch (InterruptedException e) {
        // someone waked us earlier, no problem
      }
    }

    return lock;
  }
Esempio n. 11
0
  @Test
  public void testLock() throws IOException {
    FileChannel channel = channel(regularFile(10), READ, WRITE);

    assertNotNull(channel.lock());
    assertNotNull(channel.lock(0, 10, false));
    assertNotNull(channel.lock(0, 10, true));

    assertNotNull(channel.tryLock());
    assertNotNull(channel.tryLock(0, 10, false));
    assertNotNull(channel.tryLock(0, 10, true));

    FileLock lock = channel.lock();
    assertTrue(lock.isValid());
    lock.release();
    assertFalse(lock.isValid());
  }
Esempio n. 12
0
  public static FileLock getFileLock(FileChannel fileChannel) {
    try {
      return fileChannel.tryLock();
    } catch (Exception e) {
      _logger.error(e.getMessage(), e);

      return null;
    }
  }
  public static void main(String[] args) {

    try {
      String filename = "fileToLock.dat";
      File file = new File(filename);
      file.createNewFile();

      // Creates a random access file stream to read from, and optionally
      // to write to
      FileChannel channel = new RandomAccessFile(file, "rw").getChannel();

      DataOutputStream out2 =
          new DataOutputStream(new BufferedOutputStream(new FileOutputStream(filename)));
      out2.writeDouble(3.14159);
      out2.writeChars("That was pi\n");
      out2.writeBytes("That was pi\n");
      out2.close();

      // Acquire an exclusive lock on this channel's file ( block until
      // the region can be
      // locked, this channel is closed, or the invoking thread is
      // interrupted)
      FileLock lock = channel.lock(0, Long.MAX_VALUE, false);

      System.out.print("Press any key...");
      System.in.read();
      // Attempts to acquire an exclusive lock on this channel's file
      // (does not block, an
      // invocation always returns immediately, either having acquired a
      // lock on the requested
      // region or having failed to do so.
      try {

        lock = channel.tryLock(0, Long.MAX_VALUE, true);
      } catch (OverlappingFileLockException e) {
        // thrown when an attempt is made to acquire a lock on a a file
        // that overlaps
        // a region already locked by the same JVM or when another
        // thread is already
        // waiting to lock an overlapping region of the same file
        System.out.println("Overlapping File Lock Error: " + e.getMessage());
      }

      // tells whether this lock is shared
      boolean isShared = lock.isShared();

      // release the lock
      lock.release();

      // close the channel
      channel.close();

    } catch (IOException e) {
      System.out.println("I/O Error: " + e.getMessage());
    }
  }
 @Override
 public synchronized FileLock tryLock(long position, long size, boolean shared)
     throws IOException {
   FileLock l = channel.tryLock(position, size, shared);
   if (l == null) {
     return null;
   }
   lock = new FileLockRetry(l, this);
   return lock;
 }
  /* Get a FileLock with retry. */
  private static FileLock getLockWithReTry(FileChannel channel, long position, long size)
      throws Exception {

    int retries = 0;
    FileLock lock = channel.tryLock(position, size, false);

    while (lock == null && retries <= MAX_RETRIES) {
      Thread.sleep(1000);
      lock = channel.tryLock(position, size, false);
      retries++;
    }

    if (lock == null) {
      System.err.println("Can't get a FileLock during " + MAX_RETRIES + " seconds.");
      System.exit(6);
    }

    return lock;
  }
Esempio n. 16
0
  /**
   * Creates and initializes an SPV block store. Will create the given file if it's missing. This
   * operation will block on disk.
   */
  public SPVBlockStore(NetworkParameters params, File file) throws BlockStoreException {
    checkNotNull(file);
    this.params = checkNotNull(params);
    try {
      this.numHeaders = DEFAULT_NUM_HEADERS;
      boolean exists = file.exists();
      // Set up the backing file.
      randomAccessFile = new RandomAccessFile(file, "rw");
      long fileSize = getFileSize();
      if (!exists) {
        log.info("Creating new SPV block chain file " + file);
        randomAccessFile.setLength(fileSize);
      } else if (randomAccessFile.length() != fileSize) {
        throw new BlockStoreException(
            "File size on disk does not match expected size: "
                + randomAccessFile.length()
                + " vs "
                + fileSize);
      }

      FileChannel channel = randomAccessFile.getChannel();
      fileLock = channel.tryLock();
      if (fileLock == null)
        throw new BlockStoreException("Store file is already locked by another process");

      // Map it into memory read/write. The kernel will take care of flushing writes to disk at the
      // most
      // efficient times, which may mean that until the map is deallocated the data on disk is
      // randomly
      // inconsistent. However the only process accessing it is us, via this mapping, so our own
      // view will
      // always be correct. Once we establish the mmap the underlying file and channel can go away.
      // Note that
      // the details of mmapping vary between platforms.
      buffer = channel.map(FileChannel.MapMode.READ_WRITE, 0, fileSize);

      // Check or initialize the header bytes to ensure we don't try to open some random file.
      byte[] header;
      if (exists) {
        header = new byte[4];
        buffer.get(header);
        if (!new String(header, "US-ASCII").equals(HEADER_MAGIC))
          throw new BlockStoreException("Header bytes do not equal " + HEADER_MAGIC);
      } else {
        initNewStore(params);
      }
    } catch (Exception e) {
      try {
        if (randomAccessFile != null) randomAccessFile.close();
      } catch (IOException e2) {
        throw new BlockStoreException(e2);
      }
      throw new BlockStoreException(e);
    }
  }
Esempio n. 17
0
  public boolean tryLock() {
    try {
      lockRandomAccessFile = new RandomAccessFile(lockFilePath.toFile(), "rw");
      lockChannel = lockRandomAccessFile.getChannel();
      lockFile = lockChannel.tryLock(0, 1024, false);

      return lockFile != null;
    } catch (IOException e) {
      throw new IllegalStateException("Failed to create lock in " + lockFilePath.toString(), e);
    }
  }
Esempio n. 18
0
  public static void test() throws IOException, InterruptedException {
    FileOutputStream out = new FileOutputStream("tt.txt");
    FileChannel fileChannel = out.getChannel();
    FileLock lock = fileChannel.tryLock();
    System.out.println(lock);
    for (int i = 0; i < 10; i++) {
      out.write("fjsdlfjsdlf".getBytes());
      out.write("\n".getBytes());
    }
    out.flush();

    out.close();
    Thread.sleep(10000);
  }
 private void reLock() throws IOException {
   if (lock == null) {
     return;
   }
   try {
     lock.base.release();
   } catch (IOException e) {
     // ignore
   }
   FileLock l2 = channel.tryLock(lock.position(), lock.size(), lock.isShared());
   if (l2 == null) {
     throw new IOException("Re-locking failed");
   }
   lock.base = l2;
 }
Esempio n. 20
0
  /**
   * Unlockes file
   *
   * @param file target File
   */
  @SuppressWarnings("resource")
  public static void unlock(File file) {
    try {
      FileChannel channel = new RandomAccessFile(file, "rw").getChannel();
      FileLock lock = channel.lock();
      try {
        lock = channel.tryLock();
        file.setWritable(true);
      } catch (OverlappingFileLockException e) {
      }

      lock.release();
      channel.close();
    } catch (Exception e) {
    }
  }
Esempio n. 21
0
  public DbLock(File lockFile) throws IOException {
    Preconditions.checkNotNull(lockFile, "lockFile is null");
    this.lockFile = lockFile;

    // open and lock the file
    channel = new RandomAccessFile(lockFile, "rw").getChannel();
    try {
      lock = channel.tryLock();
    } catch (IOException e) {
      Closeables.closeQuietly(channel);
      throw e;
    }

    if (lock == null) {
      throw new IOException(format("Unable to acquire lock on '%s'", lockFile.getAbsolutePath()));
    }
  }
  /**
   * Check system exec only one pro <br>
   * Created on: Nov 23, 2012 11:23:15 AM
   *
   * @param fileName
   * @return
   */
  public static boolean tryLock(String fileName) {
    /** A token representing a lock on a region of a file. */
    FileLock lock = null;

    /** A channel for reading, writing, mapping, and manipulating a file. */
    FileChannel channel = null;

    /** Instances of this class support both reading and writing to a random access file. */
    RandomAccessFile randomAccessFile = null;

    try {
      randomAccessFile = new RandomAccessFile(fileName, "rw");
      if (null != randomAccessFile) {
        channel = randomAccessFile.getChannel();
      }

      if (null != channel) {
        lock = channel.tryLock();
      }

      return (null != lock && lock.isValid());
    } catch (FileNotFoundException e) {
      System.out.println("    Project lock file [" + fileName + "] error ! PORGRAMME EXIT.");
      System.out.println(
          "MASSAGE : "
              + e.getMessage()
              + "\nCAUSE : "
              + e.getCause()
              + "\nCLASS : "
              + e.getClass());
      System.exit(1);
    } catch (IOException e) {
      System.out.println("    Project lock file [" + fileName + "] error ! PORGRAMME EXIT.");
      System.out.println(
          "MASSAGE : "
              + e.getMessage()
              + "\nCAUSE : "
              + e.getCause()
              + "\nCLASS : "
              + e.getClass());
      System.exit(1);
    }

    return false;
  }
Esempio n. 23
0
  private static void unlockFile(File file) {
    try {
      RandomAccessFile raf = new RandomAccessFile(file, "rw");
      FileChannel channel = raf.getChannel();
      try {
        if (channel.tryLock() == null) { // File is locked

          log.warn("File " + file.getAbsolutePath() + " is locked and couldn't be released");
          return;
        }
      } finally {
        channel.close(); // Unlock in either case
      }
    } catch (IOException e) {
      e.printStackTrace();
      log.error("Couldn't unlock " + file, e);
    }
  }
Esempio n. 24
0
  private FileLock obtainLock(FileChannel channel, boolean shared)
      throws TimeoutException, IOException {
    FileLock lock = null;
    int attempts = 0;
    try {
      /** Using 0x7fffffff in place of Long.MAX_VALUE. Bug # 4719967,4719605 * */
      while ((lock = channel.tryLock(0L, 0x7fffffff, shared)) == null && attempts++ < ATTEMPTS) {
        Thread.currentThread().sleep(TIMEOUT);
      }
    } catch (InterruptedException e) {
      throw new TimeoutException();
    }

    if (lock == null) {
      throw new TimeoutException();
    }
    return lock;
  }
 private void lock() throws IOException, BlockStoreException {
   if (!semaphores.tryAcquire(fileName)) {
     throw new BlockStoreException("File in use");
   }
   try {
     lock = channel.tryLock();
   } catch (OverlappingFileLockException e) {
     semaphores.release(fileName);
     lock = null;
   }
   if (lock == null) {
     try {
       this.file.close();
     } finally {
       this.file = null;
     }
     throw new BlockStoreException("Could not lock file");
   }
 }
Esempio n. 26
0
  /*
   * TODO: Finish method.
   */
  public static String readBytesFromFile(File filename)
      throws IOException, OverlappingFileLockException {
    if (!filename.exists()) {
      return null;
    }

    try {
      ByteBuffer buffer = ByteBuffer.allocate(((int) filename.getTotalSpace() * 4));
      fileReader = new FileInputStream(filename).getChannel();
      FileLock lock = fileReader.tryLock();

      if (lock != null) {
        fileReader.read(buffer);
      } else {
        throw new OverlappingFileLockException();
      }
    } finally {
      fileWriter.close();
    }

    return "";
  }
Esempio n. 27
0
  public static FileLock tryLock(File file) {
    FileLock toReturn = null;

    try {
      RandomAccessFile raf = new RandomAccessFile(file, "rw");

      try {
        FileChannel channel = raf.getChannel();
        toReturn = channel.tryLock();
        raf.writeBytes("lock file for: " + ManagementFactory.getRuntimeMXBean().getName());
      } finally {
        if (toReturn == null) raf.close();
      }
    } catch (OverlappingFileLockException e) {
      toReturn = null;
    } catch (FileNotFoundException e) {
      toReturn = null;
    } catch (IOException e) {
      toReturn = null;
    }

    return toReturn;
  }
Esempio n. 28
0
  /*
   * (non-Javadoc)
   *
   * @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest,
   *      javax.servlet.ServletResponse, javax.servlet.FilterChain)
   */
  public void doFilter(ServletRequest req, ServletResponse resp, FilterChain filterChain)
      throws IOException, ServletException {
    if (!(req instanceof HttpServletRequest) || !(resp instanceof HttpServletResponse)) {
      filterChain.doFilter(req, resp);

      return;
    }

    HttpServletRequest request = (HttpServletRequest) req;
    HttpServletResponse response = (HttpServletResponse) resp;
    String servletPath = request.getServletPath();
    Page p = pageMappings.get(servletPath);

    if (p == null) {
      // 不需要静态化的页面
      filterChain.doFilter(request, response);
      return;
    }

    String filePath = findStaticPage(request, p);
    File file = new File(pagesLocation, filePath);
    File etagFile = new File(pagesLocation, filePath + ".etag");
    FileOutputStream out = null;
    boolean fileLocked = true;
    String etagServer = findEtag(etagFile);
    String etagClient = request.getHeader("If-None-Match");
    boolean fileValid = file.isFile() && file.length() > 0 && etagServer != null;
    long expired = 0;
    if (p.cronExpression != null) {
      expired =
          p.cronExpression.getNextValidTimeAfter(new Date(file.lastModified())).getTime()
              - System.currentTimeMillis();
    } else {
      if (p.refreshInterval == Long.MAX_VALUE) {
        expired = Long.MAX_VALUE;
      } else {
        expired = System.currentTimeMillis() - file.lastModified();
        expired = expired > 0 ? p.refreshInterval - expired : p.refreshInterval;
      }
    }
    fileValid = fileValid && expired > 0;

    if (fileValid) {
      try {
        // 文件已存在,加共享锁,防止读取脏数据,同步块要尽可能的小,提高并发性
        out = new FileOutputStream(file, true);
        FileChannel fc = out.getChannel();
        FileLock fileLock = fc.tryLock(0, Long.MAX_VALUE, false);
        fileLocked = (fileLock == null || !fileLock.isValid());
      } catch (Exception ex) {
        fileLocked = true;
      } finally {
        if (out != null) {
          // 关闭共享锁文件流
          try {
            out.close();
          } catch (Exception ex) {
          }
        }
      }
    } else {
      try {
        // 清除不合法静态文件
        if (!file.isFile() || file.delete()) {
          file.getParentFile().mkdirs();
          file.createNewFile();
          // 文件不存在加排他锁,防止重复写入,同步块要尽可能的小,提高并发性
          out = new FileOutputStream(file);
          try {
            FileChannel fc = out.getChannel();
            FileLock fileLock = fc.tryLock();
            fileLocked = (fileLock == null || !fileLock.isValid());
          } catch (Exception ex) {
            fileLocked = true;
          }
          // double check lock
          etagServer = findEtag(etagFile);
          fileValid = file.isFile() && file.length() > 0 && etagServer != null;
          if (p.cronExpression != null) {
            expired =
                p.cronExpression.getNextValidTimeAfter(new Date(file.lastModified())).getTime()
                    - System.currentTimeMillis();
          } else {
            if (p.refreshInterval == Long.MAX_VALUE) {
              expired = Long.MAX_VALUE;
            } else {
              expired = System.currentTimeMillis() - file.lastModified();
              expired = expired > 0 ? p.refreshInterval - expired : p.refreshInterval;
            }
          }
          fileValid = fileValid && expired > 0;
        } else {
          fileLocked = true;
        }
      } catch (Exception ex) {
        fileLocked = true;
      } finally {
        if (fileLocked && out != null) {
          // 关闭排他锁文件流
          try {
            out.close();
          } catch (Exception ex) {
          }
        }
      }
    }

    if (fileLocked) {
      // 静态页面正在写入,跳过静态化
      if (expired != Long.MAX_VALUE) {
        expired = expired < 0 ? 0 : expired / 1000;
        response.setHeader("cache-control", "max-age=" + expired);
      }
      filterChain.doFilter(request, response);
      return;
    }

    if (fileValid) {
      response.setHeader("etag", etagServer);
      if (etagServer.equalsIgnoreCase(etagClient)) {
        response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
      } else {
        // 静态页面合法,直接跳转过去
        StringBuilder sb = new StringBuilder();
        sb.append(prefix);
        sb.append(filePath);

        if ("web".equals(xSendFileKey)) {
          // 直接使用web容器返回
          RequestDispatcher dispatcher = request.getRequestDispatcher(sb.toString());

          dispatcher.forward(request, response);
        } else {
          // 使用http服务器进行加速
          response.setHeader(xSendFileKey, sb.toString());
          if (expired != Long.MAX_VALUE) {
            expired = expired < 0 ? 0 : expired / 1000;
            response.setHeader("cache-control", "max-age=" + expired);
          }
        }
      }
    } else {
      // 静态页面不存在或者已过期
      StaticizeResponse res = null;

      try {
        res = new StaticizeResponse(response, out, file);
        if (expired != Long.MAX_VALUE) {
          expired = expired < 0 ? 0 : expired / 1000;
          response.setHeader("cache-control", "max-age=" + expired);
        }
        // md5还没生成先写入空值的md5值,下次请求返回正确的md5值
        response.setHeader("etag", "d41d8cd98f00b204e9800998ecf8427e");
        filterChain.doFilter(request, res);
      } finally {
        if (res != null) {
          try {
            res.flushBuffer();
            res.close();
          } catch (Exception ex) {
          }
          etagServer = res.getMd5();
          saveEtag(etagFile, etagServer);
        }
      }
    }
  }
 @Override
 public FileLock tryLock(long position, long size, boolean shared) throws IOException {
   return base.tryLock(position, size, shared);
 }
 @Override
 public synchronized FileLock tryLock(long position, long size, boolean shared)
     throws IOException {
   return readBase.tryLock(position, size, shared);
 }