BufferedRandomAccessFile
is like a
+ * RandomAccessFile
, but it uses a private buffer so that most
+ * operations do not require a disk access.
+ *
+ *
+ * Note: The operations on this class are unmonitored. Also, the correct
+ * functioning of the RandomAccessFile
methods that are not
+ * overridden here relies on the implementation of those methods in the
+ * superclass.
+ * Author : Avinash Lakshman ( alakshman@facebook.com) & Prashant Malik ( pmalik@facebook.com )
+ */
+
+public final class BufferedRandomAccessFile extends RandomAccessFile {
+ //private static final Logger logger_ = Logger.getLogger(BufferedRandomAccessFile.class);
+ static final int LogBuffSz_ = 16; // 64K buffer
+ public static final int BuffSz_ = (1 << LogBuffSz_);
+ static final long BuffMask_ = ~(((long) BuffSz_) - 1L);
+
+ /*
+ * This implementation is based on the buffer implementation in Modula-3's
+ * "Rd", "Wr", "RdClass", and "WrClass" interfaces.
+ */
+ private boolean dirty_; // true iff unflushed bytes exist
+ private boolean closed_; // true iff the file is closed
+ private long curr_; // current position in file
+ private long lo_, hi_; // bounds on characters in "buff"
+ private byte[] buff_; // local buffer
+ private long maxHi_; // this.lo + this.buff.length
+ private boolean hitEOF_; // buffer contains last file block?
+ private long diskPos_; // disk position
+
+ /*
+ * To describe the above fields, we introduce the following abstractions for
+ * the file "f":
+ *
+ * len(f) the length of the file curr(f) the current position in the file
+ * c(f) the abstract contents of the file disk(f) the contents of f's
+ * backing disk file closed(f) true iff the file is closed
+ *
+ * "curr(f)" is an index in the closed interval [0, len(f)]. "c(f)" is a
+ * character sequence of length "len(f)". "c(f)" and "disk(f)" may differ if
+ * "c(f)" contains unflushed writes not reflected in "disk(f)". The flush
+ * operation has the effect of making "disk(f)" identical to "c(f)".
+ *
+ * A file is said to be *valid* if the following conditions hold:
+ *
+ * V1. The "closed" and "curr" fields are correct:
+ *
+ * f.closed == closed(f) f.curr == curr(f)
+ *
+ * V2. The current position is either contained in the buffer, or just past
+ * the buffer:
+ *
+ * f.lo <= f.curr <= f.hi
+ *
+ * V3. Any (possibly) unflushed characters are stored in "f.buff":
+ *
+ * (forall i in [f.lo, f.curr): c(f)[i] == f.buff[i - f.lo])
+ *
+ * V4. For all characters not covered by V3, c(f) and disk(f) agree:
+ *
+ * (forall i in [f.lo, len(f)): i not in [f.lo, f.curr) => c(f)[i] ==
+ * disk(f)[i])
+ *
+ * V5. "f.dirty" is true iff the buffer contains bytes that should be
+ * flushed to the file; by V3 and V4, only part of the buffer can be dirty.
+ *
+ * f.dirty == (exists i in [f.lo, f.curr): c(f)[i] != f.buff[i - f.lo])
+ *
+ * V6. this.maxHi == this.lo + this.buff.length
+ *
+ * Note that "f.buff" can be "null" in a valid file, since the range of
+ * characters in V3 is empty when "f.lo == f.curr".
+ *
+ * A file is said to be *ready* if the buffer contains the current position,
+ * i.e., when:
+ *
+ * R1. !f.closed && f.buff != null && f.lo <= f.curr && f.curr < f.hi
+ *
+ * When a file is ready, reading or writing a single byte can be performed
+ * by reading or writing the in-memory buffer without performing a disk
+ * operation.
+ */
+
+ /**
+ * Open a new BufferedRandomAccessFile
on file
+ * in mode mode
, which should be "r" for reading only, or
+ * "rw" for reading and writing.
+ */
+ public BufferedRandomAccessFile(File file, String mode) throws IOException {
+ super(file, mode);
+ this.init(0);
+ }
+
+ public BufferedRandomAccessFile(File file, String mode, int size) throws IOException {
+ super(file, mode);
+ this.init(size);
+ }
+
+ /**
+ * Open a new BufferedRandomAccessFile
on the file named
+ * name
in mode mode
, which should be "r" for
+ * reading only, or "rw" for reading and writing.
+ */
+ public BufferedRandomAccessFile(String name, String mode) throws IOException {
+ super(name, mode);
+ this.init(0);
+ }
+
+ public BufferedRandomAccessFile(String name, String mode, int size) throws FileNotFoundException {
+ super(name, mode);
+ this.init(size);
+ }
+
+ private void init(int size) {
+ this.dirty_ = this.closed_ = false;
+ this.lo_ = this.curr_ = this.hi_ = 0;
+ this.buff_ = (size > BuffSz_) ? new byte[size] : new byte[BuffSz_];
+ this.maxHi_ = (long) BuffSz_;
+ this.hitEOF_ = false;
+ this.diskPos_ = 0L;
+ }
+
+ public void close() throws IOException {
+ this.flush();
+ this.closed_ = true;
+ super.close();
+ }
+
+ /**
+ * Flush any bytes in the file's buffer that have not yet been written to
+ * disk. If the file was created read-only, this method is a no-op.
+ */
+ public void flush() throws IOException {
+ this.flushBuffer();
+ }
+
+ /* Flush any dirty bytes in the buffer to disk. */
+ private void flushBuffer() throws IOException {
+ if (this.dirty_) {
+ if (this.diskPos_ != this.lo_) super.seek(this.lo_);
+ int len = (int) (this.curr_ - this.lo_);
+ super.write(this.buff_, 0, len);
+ this.diskPos_ = this.curr_;
+ this.dirty_ = false;
+ }
+ }
+
+ /*
+ * Read at most "this.buff.length" bytes into "this.buff", returning the
+ * number of bytes read. If the return result is less than
+ * "this.buff.length", then EOF was read.
+ */
+ private int fillBuffer() throws IOException {
+ int cnt = 0;
+ int rem = this.buff_.length;
+ while (rem > 0) {
+ int n = super.read(this.buff_, cnt, rem);
+ if (n < 0) break;
+ cnt += n;
+ rem -= n;
+ }
+ if ((cnt < 0) && (this.hitEOF_ = (cnt < this.buff_.length))) {
+ // make sure buffer that wasn't read is initialized with -1
+ Arrays.fill(this.buff_, cnt, this.buff_.length, (byte) 0xff);
+ }
+ this.diskPos_ += cnt;
+ return cnt;
+ }
+
+ /*
+ * This method positions this.curr
at position pos
.
+ * If pos
does not fall in the current buffer, it flushes the
+ * current buffer and loads the correct one.
+ *
+ * On exit from this routine this.curr == this.hi
iff pos
+ * is at or past the end-of-file, which can only happen if the file was
+ * opened in read-only mode.
+ */
+ public void seek(long pos) throws IOException {
+ if (pos >= this.hi_ || pos < this.lo_) {
+ // seeking outside of current buffer -- flush and read
+ this.flushBuffer();
+ this.lo_ = pos & BuffMask_; // start at BuffSz boundary
+ this.maxHi_ = this.lo_ + (long) this.buff_.length;
+ if (this.diskPos_ != this.lo_) {
+ super.seek(this.lo_);
+ this.diskPos_ = this.lo_;
+ }
+ int n = this.fillBuffer();
+ this.hi_ = this.lo_ + (long) n;
+ } else {
+ // seeking inside current buffer -- no read required
+ if (pos < this.curr_) {
+ // if seeking backwards, we must flush to maintain V4
+ this.flushBuffer();
+ }
+ }
+ this.curr_ = pos;
+ }
+
+ public long getFilePointer() {
+ return this.curr_;
+ }
+
+ public long length() throws IOException {
+ return Math.max(this.curr_, super.length());
+ }
+
+ public int read() throws IOException {
+ if (this.curr_ >= this.hi_) {
+ // test for EOF
+ // if (this.hi < this.maxHi) return -1;
+ if (this.hitEOF_) return -1;
+
+ // slow path -- read another buffer
+ this.seek(this.curr_);
+ if (this.curr_ == this.hi_) return -1;
+ }
+ byte res = this.buff_[(int) (this.curr_ - this.lo_)];
+ this.curr_++;
+ return ((int) res) & 0xFF; // convert byte -> int
+ }
+
+ public int read(byte[] b) throws IOException {
+ return this.read(b, 0, b.length);
+ }
+
+ public int read(byte[] b, int off, int len) throws IOException {
+ if (this.curr_ >= this.hi_) {
+ // test for EOF
+ // if (this.hi < this.maxHi) return -1;
+ if (this.hitEOF_) return -1;
+
+ // slow path -- read another buffer
+ this.seek(this.curr_);
+ if (this.curr_ == this.hi_) return -1;
+ }
+ len = Math.min(len, (int) (this.hi_ - this.curr_));
+ int buffOff = (int) (this.curr_ - this.lo_);
+ System.arraycopy(this.buff_, buffOff, b, off, len);
+ this.curr_ += len;
+ return len;
+ }
+
+ public void write(int b) throws IOException {
+ if (this.curr_ >= this.hi_) {
+ if (this.hitEOF_ && this.hi_ < this.maxHi_) {
+ // at EOF -- bump "hi"
+ this.hi_++;
+ } else {
+ // slow path -- write current buffer; read next one
+ this.seek(this.curr_);
+ if (this.curr_ == this.hi_) {
+ // appending to EOF -- bump "hi"
+ this.hi_++;
+ }
+ }
+ }
+ this.buff_[(int) (this.curr_ - this.lo_)] = (byte) b;
+ this.curr_++;
+ this.dirty_ = true;
+ }
+
+ public void write(byte[] b) throws IOException {
+ this.write(b, 0, b.length);
+ }
+
+ public void write(byte[] b, int off, int len) throws IOException {
+ while (len > 0) {
+ int n = this.writeAtMost(b, off, len);
+ off += n;
+ len -= n;
+ this.dirty_ = true;
+ }
+ }
+
+ /*
+ * Write at most "len" bytes to "b" starting at position "off", and return
+ * the number of bytes written.
+ */
+ private int writeAtMost(byte[] b, int off, int len) throws IOException {
+ if (this.curr_ >= this.hi_) {
+ if (this.hitEOF_ && this.hi_ < this.maxHi_) {
+ // at EOF -- bump "hi"
+ this.hi_ = this.maxHi_;
+ } else {
+ // slow path -- write current buffer; read next one
+ this.seek(this.curr_);
+ if (this.curr_ == this.hi_) {
+ // appending to EOF -- bump "hi"
+ this.hi_ = this.maxHi_;
+ }
+ }
+ }
+ len = Math.min(len, (int) (this.hi_ - this.curr_));
+ int buffOff = (int) (this.curr_ - this.lo_);
+ System.arraycopy(b, off, this.buff_, buffOff, len);
+ this.curr_ += len;
+ return len;
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/arialyy/simple/single_task/SingleTaskActivity.java b/app/src/main/java/com/arialyy/simple/single_task/SingleTaskActivity.java
index 7bc60d51..4d0bdff2 100644
--- a/app/src/main/java/com/arialyy/simple/single_task/SingleTaskActivity.java
+++ b/app/src/main/java/com/arialyy/simple/single_task/SingleTaskActivity.java
@@ -33,6 +33,8 @@ import butterknife.Bind;
import com.arialyy.aria.core.AMTarget;
import com.arialyy.aria.core.Aria;
import com.arialyy.aria.core.DownloadEntity;
+import com.arialyy.aria.core.task.DownloadUtil;
+import com.arialyy.aria.core.task.IDownloadListener;
import com.arialyy.aria.core.task.Task;
import com.arialyy.aria.util.CommonUtil;
import com.arialyy.frame.util.show.L;
@@ -198,6 +200,67 @@ public class SingleTaskActivity extends BaseActivity
RandomAccessFile
methods that are not
* overridden here relies on the implementation of those methods in the
* superclass.
- * Author : Avinash Lakshman ( alakshman@facebook.com) & Prashant Malik ( pmalik@facebook.com )
+ * Author : Avinash Lakshman ( alakshman@facebook.com) Prashant Malik ( pmalik@facebook.com )
*/
public final class BufferedRandomAccessFile extends RandomAccessFile {
diff --git a/README.md b/README.md
index ddc19c92..fbff9751 100644
--- a/README.md
+++ b/README.md
@@ -17,7 +17,7 @@ Aria,致力于让下载傻瓜化
## 下载
[![Download](https://api.bintray.com/packages/arialyy/maven/Aria/images/download.svg)](https://bintray.com/arialyy/maven/Aria/_latestVersion)
```java
-compile 'com.arialyy.aria:Aria:2.4.0'
+compile 'com.arialyy.aria:Aria:2.4.1'
```
## 示例
@@ -134,6 +134,7 @@ Aria支持https下载,如果你希望使用自己的ca证书,那么你需要
***
## 开发日志
+ + v_2.4.1 修复下载慢的问题,修复application、service 不能使用的问题
+ v_2.4.0 支持https链接下载
+ v_2.3.8 修复数据错乱的bug、添加fragment支持
+ v_2.3.6 添加dialog、popupWindow支持
From 53d449c72dd11e0f170723d1c4844188136d8888 Mon Sep 17 00:00:00 2001
From: AriaLyy <511455842@qq.com>
Date: Thu, 23 Feb 2017 19:22:57 +0800
Subject: [PATCH 21/24] ..
---
.idea/misc.xml | 2 +-
.../main/java/com/arialyy/aria/core/task/SingleThreadTask.java | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/.idea/misc.xml b/.idea/misc.xml
index fbb68289..5d199810 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -37,7 +37,7 @@