Skip to content
This repository has been archived by the owner on Sep 14, 2018. It is now read-only.

Commit

Permalink
更新至2.42
Browse files Browse the repository at this point in the history
优化文件写入方式,32位系统不用合并文件
插件更新调整,会缓存一份在本地
百度云下载提示未选择文件BUG修复
配置保存后重启不生效问题
修复某些情况下重启软件后窗口不显示的BUG
  • Loading branch information
monkeyWie committed Mar 28, 2018
1 parent 1b84586 commit ce4dad9
Show file tree
Hide file tree
Showing 19 changed files with 131 additions and 196 deletions.
2 changes: 1 addition & 1 deletion common/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<artifactId>proxyee-down</artifactId>
<groupId>lee.study</groupId>
<version>2.41</version>
<version>2.42</version>
</parent>
<modelVersion>4.0.0</modelVersion>

Expand Down
6 changes: 3 additions & 3 deletions core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<artifactId>proxyee-down</artifactId>
<groupId>lee.study</groupId>
<version>2.41</version>
<version>2.42</version>
</parent>
<modelVersion>4.0.0</modelVersion>

Expand All @@ -18,10 +18,10 @@
<artifactId>proxyee-down-common</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<!--<dependency>
<groupId>org.xerial.larray</groupId>
<artifactId>larray_2.12</artifactId>
<version>0.4.0</version>
</dependency>
</dependency>-->
</dependencies>
</project>
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@
import io.netty.handler.codec.http.HttpHeaderNames;
import io.netty.handler.ssl.SslContext;
import io.netty.resolver.NoopAddressResolverGroup;
import java.io.Closeable;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.util.HashMap;
import java.util.Map;
Expand Down Expand Up @@ -67,7 +67,12 @@ public void startDown() throws Exception {
if (new File(taskInfo.buildTaskFilePath()).exists()) {
throw new BootstrapException("文件名已存在,请修改文件名");
}
initBoot();
//创建文件
try (
RandomAccessFile randomAccessFile = new RandomAccessFile(taskInfo.buildTaskFilePath(), "rw")
) {
randomAccessFile.setLength(taskInfo.getTotalSize());
}
//文件下载开始回调
taskInfo.reset();
taskInfo.setStatus(HttpDownStatus.RUNNING);
Expand All @@ -81,6 +86,7 @@ public void startDown() throws Exception {
if (callback != null) {
callback.onStart(httpDownInfo);
}
afterStart();
}

protected void startChunkDown(ChunkInfo chunkInfo, int updateStatus) throws Exception {
Expand Down Expand Up @@ -200,13 +206,17 @@ public void continueDown()
throws Exception {
TaskInfo taskInfo = httpDownInfo.getTaskInfo();
synchronized (taskInfo) {
if (continueDownHandle()) {
if (!FileUtil.exists(taskInfo.buildTaskFilePath())) {
close();
startDown();
} else {
taskInfo.setStatus(HttpDownStatus.RUNNING);
taskInfo.getChunkInfoList().forEach((chunk) -> chunk.setErrorCount(0));
long curTime = System.currentTimeMillis();
taskInfo.setPauseTime(
taskInfo.getPauseTime() + (curTime - taskInfo.getLastTime()));
taskInfo.setLastTime(curTime);
afterStart();
for (ChunkInfo chunkInfo : taskInfo.getChunkInfoList()) {
synchronized (chunkInfo) {
if (chunkInfo.getStatus() == HttpDownStatus.PAUSE
Expand All @@ -224,21 +234,16 @@ public void continueDown()
}
}

protected abstract boolean continueDownHandle() throws Exception;

public abstract void merge() throws Exception;

public void close(ChunkInfo chunkInfo) {
try {
if (!attr.containsKey(chunkInfo.getIndex())) {
return;
}
Channel channel = getChannel(chunkInfo);
Closeable[] fileChannels = getFileWriter(chunkInfo);
LOGGER.debug(
"下载连接关闭:channelId[" + (channel != null ? channel.id() : "null") + "]\t" + chunkInfo);
attr.remove(chunkInfo.getIndex());
HttpDownUtil.safeClose(channel, fileChannels);
HttpDownUtil.safeClose(channel);
} catch (Exception e) {
LOGGER.error("closeChunk error", e);
}
Expand Down Expand Up @@ -299,14 +304,9 @@ public Channel getChannel(ChunkInfo chunkInfo) {
return (Channel) getAttr(chunkInfo, ATTR_CHANNEL);
}

protected abstract void initBoot() throws Exception;

public abstract Closeable[] initFileWriter(ChunkInfo chunkInfo) throws Exception;
protected void afterStart() throws Exception {
}

public abstract int doFileWriter(ChunkInfo chunkInfo, ByteBuffer buffer)
throws IOException;

protected Closeable[] getFileWriter(ChunkInfo chunkInfo) {
return (Closeable[]) getAttr(chunkInfo, ATTR_FILE_CHANNELS);
}
}
39 changes: 3 additions & 36 deletions core/src/main/java/lee/study/down/boot/X64HttpDownBootstrap.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,12 @@

import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.handler.ssl.SslContext;
import java.io.Closeable;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import lee.study.down.dispatch.HttpDownCallback;
import lee.study.down.io.Mmap;
import lee.study.down.model.ChunkInfo;
import lee.study.down.model.HttpDownInfo;
import lee.study.down.model.TaskInfo;
import lee.study.down.util.FileUtil;

public class X64HttpDownBootstrap extends AbstractHttpDownBootstrap {

Expand All @@ -27,38 +23,9 @@ public X64HttpDownBootstrap(HttpDownInfo httpDownInfo,
}

@Override
public boolean continueDownHandle() throws Exception {
TaskInfo taskInfo = getHttpDownInfo().getTaskInfo();
if (!FileUtil.exists(taskInfo.buildTaskFilePath())) {
close();
startDown();
return false;
}
return true;
}

@Override
public void merge() throws Exception {

}

@Override
public void initBoot() throws IOException {
TaskInfo taskInfo = getHttpDownInfo().getTaskInfo();
try (
RandomAccessFile randomAccessFile = new RandomAccessFile(taskInfo.buildTaskFilePath(), "rw")
) {
randomAccessFile.setLength(taskInfo.getTotalSize());
}
}

@Override
public Closeable[] initFileWriter(ChunkInfo chunkInfo) throws Exception {
if (mmap == null) {
mmap = new Mmap(getHttpDownInfo().getTaskInfo().buildTaskFilePath(),
getHttpDownInfo().getTaskInfo().getTotalSize());
}
return null;
public void afterStart() throws Exception {
mmap = new Mmap(getHttpDownInfo().getTaskInfo().buildTaskFilePath(),
getHttpDownInfo().getTaskInfo().getTotalSize());
}

@Override
Expand Down
112 changes: 13 additions & 99 deletions core/src/main/java/lee/study/down/boot/X86HttpDownBootstrap.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,19 @@

import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.handler.ssl.SslContext;
import java.io.Closeable;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.FileChannel.MapMode;
import java.util.LinkedList;
import java.util.List;
import lee.study.down.constant.HttpDownStatus;
import lee.study.down.dispatch.HttpDownCallback;
import lee.study.down.model.ChunkInfo;
import lee.study.down.model.HttpDownInfo;
import lee.study.down.model.TaskInfo;
import lee.study.down.util.FileUtil;

public class X86HttpDownBootstrap extends AbstractHttpDownBootstrap {

private static final String ATTR_CACHE = "cache";

public X86HttpDownBootstrap(HttpDownInfo httpDownInfo,
int retryCount,
SslContext clientSslContext,
Expand All @@ -31,101 +24,22 @@ public X86HttpDownBootstrap(HttpDownInfo httpDownInfo,
super(httpDownInfo, retryCount, clientSslContext, clientLoopGroup, callback, timeoutCheckTask);
}

@Override
public void initBoot() throws Exception {
TaskInfo taskInfo = getHttpDownInfo().getTaskInfo();
if (taskInfo.getChunkInfoList().size() > 1) {
FileUtil.deleteIfExists(taskInfo.buildChunksPath());
FileUtil.createDirSmart(taskInfo.buildChunksPath());
FileUtil.createFile(taskInfo.buildTaskFilePath());
}
}

@Override
public boolean continueDownHandle() throws Exception {
TaskInfo taskInfo = getHttpDownInfo().getTaskInfo();
if (taskInfo.getStatus() == HttpDownStatus.MERGE_CANCEL) {
merge();
} else if (!FileUtil.exists(taskInfo.buildChunksPath())) {
close();
startDown();
} else {
return true;
}
return false;
}

@Override
public void merge() throws Exception {
/*TaskInfo taskInfo = getHttpDownInfo().getTaskInfo();
String filePath = taskInfo.buildTaskFilePath();
long position = 0;
taskInfo.setStatus(HttpDownStatus.MERGE);
if (getCallback() != null) {
getCallback().onMerge(getHttpDownInfo());
}
synchronized (taskInfo) {
try (
FileChannel targetChannel = new RandomAccessFile(filePath, "rw").getChannel()
) {
for (ChunkInfo chunkInfo : taskInfo.getChunkInfoList()) {
try (
FileChannel chunkChannel = new RandomAccessFile(
taskInfo.buildChunkFilePath(chunkInfo.getIndex()), "rw").getChannel()
) {
long remaining = chunkChannel.size();
while (remaining > 0) {
long transferred = targetChannel.transferFrom(chunkChannel, position, remaining);
remaining -= transferred;
position += transferred;
}
}
}
}
}
FileUtil.deleteIfExists(taskInfo.buildChunksPath());*/
}

@Override
public Closeable[] initFileWriter(ChunkInfo chunkInfo) throws Exception {
setAttr(chunkInfo, "cache", new LinkedList<ByteBuffer>());
return null;
}


@Override
public int doFileWriter(ChunkInfo chunkInfo, ByteBuffer buffer) throws IOException {
int ret = -1;
List<ByteBuffer> cache = (List<ByteBuffer>) getAttr(chunkInfo, ATTR_CACHE);
if (cache != null) {
cache.add(buffer);
if (cache.size() == 64) {
ret = cacheFlush(chunkInfo);
int ret = buffer.remaining();
MappedByteBuffer mappedByteBuffer = null;
try (
FileChannel fileChannel = new RandomAccessFile(
getHttpDownInfo().getTaskInfo().buildTaskFilePath(), "rw").getChannel()
) {
mappedByteBuffer = fileChannel
.map(MapMode.READ_WRITE, chunkInfo.getNowStartPosition() + chunkInfo.getDownSize(), ret);
mappedByteBuffer.put(buffer);
} finally {
if (mappedByteBuffer != null) {
FileUtil.unmap(mappedByteBuffer);
}
}
return ret;
}

public int getCacheSize(ChunkInfo chunkInfo) {
List<ByteBuffer> cache = (List<ByteBuffer>) getAttr(chunkInfo, ATTR_CACHE);
if (cache != null && cache.size() > 0) {
return cache.stream().map(bc -> bc.remaining()).reduce((r1, r2) -> r1 + r2).get();
}
return 0;
}

public int cacheFlush(ChunkInfo chunkInfo) throws IOException {
int ret = getCacheSize(chunkInfo);
if (ret > 0) {
List<ByteBuffer> cache = (List<ByteBuffer>) getAttr(chunkInfo, ATTR_CACHE);
MappedByteBuffer mappedByteBuffer = new RandomAccessFile(
getHttpDownInfo().getTaskInfo().buildTaskFilePath(), "rw").getChannel()
.map(MapMode.READ_WRITE, chunkInfo.getNowStartPosition() + chunkInfo.getDownSize(),
ret);
cache.forEach(bc -> mappedByteBuffer.put(bc));
cache.clear();
FileUtil.unmap(mappedByteBuffer);
}
return ret;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,8 @@
import io.netty.handler.codec.http.HttpResponse;
import io.netty.handler.codec.http.LastHttpContent;
import io.netty.util.ReferenceCountUtil;
import java.io.Closeable;
import java.io.IOException;
import lee.study.down.boot.AbstractHttpDownBootstrap;
import lee.study.down.boot.X86HttpDownBootstrap;
import lee.study.down.constant.HttpDownStatus;
import lee.study.down.dispatch.HttpDownCallback;
import lee.study.down.model.ChunkInfo;
Expand Down Expand Up @@ -53,7 +51,6 @@ protected void initChannel(Channel ch) throws Exception {
.addLast("httpCodec", new HttpClientCodec());
ch.pipeline().addLast(new ChannelInboundHandlerAdapter() {

private Closeable[] fileChannels;
private TaskInfo taskInfo = bootstrap.getHttpDownInfo().getTaskInfo();
private HttpDownCallback callback = bootstrap.getCallback();

Expand All @@ -71,14 +68,6 @@ public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception
if (chunkInfo.getStatus() == HttpDownStatus.RUNNING
&& nowChannel == ctx.channel()) {
int readableBytes = bootstrap.doFileWriter(chunkInfo, byteBuf.nioBuffer());
if (bootstrap instanceof X86HttpDownBootstrap) {
X86HttpDownBootstrap x86Bootstrap = (X86HttpDownBootstrap) bootstrap;
long downSize = chunkInfo.getDownSize() + x86Bootstrap.getCacheSize(chunkInfo);
//下载完成
if (isDone(downSize, httpContent) || isContinue(downSize)) {
readableBytes = x86Bootstrap.cacheFlush(chunkInfo);
}
}
if (readableBytes > 0) {
//文件已下载大小
chunkInfo.setDownSize(chunkInfo.getDownSize() + readableBytes);
Expand All @@ -87,7 +76,6 @@ public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception
callback.onProgress(bootstrap.getHttpDownInfo(), chunkInfo);
}
} else {

return;
}
} else {
Expand All @@ -112,9 +100,6 @@ public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception
taskInfo.setTotalSize(taskInfo.getDownSize());
taskInfo.getChunkInfoList().get(0).setTotalSize(taskInfo.getDownSize());
}
if (taskInfo.getChunkInfoList().size() > 1) {
bootstrap.merge();
}
//文件下载完成回调
taskInfo.setStatus(HttpDownStatus.DONE);
LOGGER.debug("下载完成:channelId[" + ctx.channel().id() + "]\t" + chunkInfo);
Expand Down Expand Up @@ -146,7 +131,6 @@ public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception
+ "]" + chunkInfo);
chunkInfo
.setDownSize(chunkInfo.getNowStartPosition() - chunkInfo.getOriStartPosition());
fileChannels = bootstrap.initFileWriter(chunkInfo);
chunkInfo.setStatus(HttpDownStatus.RUNNING);
if (callback != null) {
callback.onChunkConnected(bootstrap.getHttpDownInfo(), chunkInfo);
Expand Down Expand Up @@ -185,7 +169,7 @@ public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {

private void safeClose(Channel channel) {
try {
HttpDownUtil.safeClose(channel, fileChannels);
HttpDownUtil.safeClose(channel);
} catch (IOException e) {
LOGGER.error("safeClose fail:", e);
}
Expand Down
Loading

0 comments on commit ce4dad9

Please sign in to comment.