简单的数组越界,帮看下

bawgiitx 2010-03-25 05:29:29

while ((n = buffer.read(b, 0, 1366)) != -1) {
try{
System.arraycopy(b, 0, buff, st, n);//出错
} catch (Exception ee) {//13987
System.out.println(Thread.currentThread() + "st:" + st + ",n:" + n);
System.out.println((1366*1024 -st)+" "+ee.toString());
}
synchronized (ITHIS) {
down_len += n;
}
st += n;
}
/*错误
Thread[Thread-1,5,main]st:1397486,n:1299
1298 java.lang.ArrayIndexOutOfBoundsException
Thread[Thread-2,5,main]st:1398300,n:485
484 java.lang.ArrayIndexOutOfBoundsException
*/


//全代码

import java.io.*;
import java.net.*;
import java.util.logging.*;

public class downfile {

final downfile ITHIS = this;

public static void main(String[] args) {
downfile d = new downfile();
d.from_url = "http://202.103.221.29:81/bk/UploadFiles/2007-3/37572051.mp3";
d.to_file = "d:/1.mp3";
d.start();
}
String from_url;
String to_file;
/**
* 文件总长度
*/
long file_length;
int ids;
/**
* 是否已下载,第1366*1024Byte(1.33MB)为一单位
*/
boolean[] is_downs;
ToolDownload[] threan_down;
long down_len;
long down_all_len;

public synchronized int getId() {
for (int i = 0; i < ids; i++) {
if (!is_downs[i]) {
is_downs[i] = true;
return i;
}
}
return -1;
}

/**
* 开始任务
*/
void start() {
try {
URLConnection con = new URL(from_url).openConnection();
file_length = con.getContentLength();
ids = (int) (file_length / (1366 * 1024));
if (file_length % (1366 * 1024) > 0) {
ids++;
}
System.out.println("ids" + ids);
is_downs = new boolean[ids];
if (ids > 10) {
threan_down = new ToolDownload[10];
for (int i = 0; i < 10; i++) {
threan_down[i] = new ToolDownload();
}
} else {
threan_down = new ToolDownload[ids];
for (int i = 0; i < ids; i++) {
threan_down[i] = new ToolDownload();
}
}
new Thread(new Runnable() {

long time = System.currentTimeMillis() / 1000;

public void run() {
while (ITHIS.file_length > ITHIS.down_all_len) {
synchronized (ITHIS) {
System.out.println((ITHIS.down_len / 1024 / 1.0) + "kb/s");
ITHIS.down_all_len += ITHIS.down_len;
ITHIS.down_len = 0;
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
}
}
}
System.out.println("文件下载完毕");
System.out.println("下载所用总时间: " + (System.currentTimeMillis() / 1000 - time) + "s");
}
}).start();
for (ToolDownload td : threan_down) {
td.down(getId());
}
} catch (IOException ex) {
Logger.getLogger(downfile.class.getName()).log(Level.SEVERE, null, ex);
}
}

class ToolDownload extends Thread {

URL url = null;
URLConnection con = null;
RandomAccessFile rand;
int id;
byte[] b = new byte[1366];
byte[] buff = new byte[1366 * 1024];
int st;
int n;
boolean is_start = false;

ToolDownload() {
try {
url = new URL(from_url);
con = url.openConnection();
con.setAllowUserInteraction(true);
rand = new RandomAccessFile(new File(to_file), "rw");
} catch (IOException ex) {
Logger.getLogger(downfile.class.getName()).log(Level.SEVERE, null, ex);
}
}

/**
* 下载第id段文件
*/
void down(final int id) {
if (id < 0) {
return;
}
this.id = id;
this.start();
}

@Override
public void run() {
synchronized (ITHIS) {
if (is_start) {
return;
}
is_start = true;
}
try {
System.out.println("线程" + this.getName() + "启动...");
con.setRequestProperty("Range", "bytes=" + (id * 1366 * 1024) + "-" + ((id + 1) * 1366 * 1024 > file_length ? file_length : (id + 1) * 1366 * 1024));
BufferedInputStream buffer = new BufferedInputStream(con.getInputStream());
n = 0;
st = 0;
while ((n = buffer.read(b, 0, 1366)) != -1) {
try{
System.arraycopy(b, 0, buff, st, n);
} catch (Exception ee) {//13987
System.out.println(Thread.currentThread() + "st:" + st + ",n:" + n);
System.out.println((1366*1024 -st)+" "+ee.toString());
}
synchronized (ITHIS) {
down_len += n;
}
st += n;
}
rand.seek(id * 1366 * 1024);
rand.write(buff);
System.out.println("线程" + this.getName() + "下载完毕");
buffer.close();
} catch (Exception ee) {
ee.printStackTrace();
}
is_start = false;
down(ITHIS.getId());
}
}
}

...全文
286 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
py330316117 2010-03-28
  • 打赏
  • 举报
回复
在你bb之前你先把下面的这几个值给我解释下
b,buff, st
然后告诉我他们的值,再告诉我通过n = buffer.read(b, 0, 1366)你能得到以上3个哪个的值,
然后你再看看我发的帖子说的是什么问题,是问你给n赋值还是以上3个,我只能给你一个解释,
虽然你说n = buffer.read(b, 0, 1366)是给n赋值我不反对,但是(n = buffer.read(b, 0, 1366)) != -1
是进行判断你觉得那?而且我也没问你n的值,我问
引用 3 楼 bayougeng 的回复:

2楼你肯定没仔细看代码。
楼主你的while循环中没有关于越界的判断,也就是说,你总是假设你的缓冲区能装下整个文件。
这显然是不现实的。你应该加入清理缓冲区的操作。
你的debug信息看起来已经很清楚了,告诉你超过了缓冲区的大小。

你仔细看了,哪你告诉我他们的值都是什么


你就给我回答

while ((n = buffer.read(b, 0, 1366)) != -1) {
try{
System.arraycopy(b, 0, buff, st, n);
} catch (Exception ee) {//13987
System.out.println(Thread.currentThread() + "st:" + st + ",n:" + n);
System.out.println((1366*1024 -st)+" "+ee.toString());
}
synchronized (ITHIS) {
down_len += n;
}
st += n;
}
在 while中给n赋值,每次循环体结束后重置st。
buff是缓冲区,在while的括号中进行填充


你敲下代码看看能出来值不,能出来你在说没用的
py330316117 2010-03-28
  • 打赏
  • 举报
回复
狗b我见得多了 ,没见过sb,不知道是哪个狗生下来的狗崽,一下生除了骂人不会别的,你有种就去开贴吧,看看是谁只会叫唤,我是骂你了还是caonima了,你真个鸡巴德行,除了说别人没素质你还会caonima吧,和你爸一起cao是不
bayougeng 2010-03-27
  • 打赏
  • 举报
回复
学艺不精不要紧,要是错了还鸭子死了嘴硬,那我只能说是一种悲哀。
bayougeng 2010-03-27
  • 打赏
  • 举报
回复
楼上的,我真的很无语。
瞧瞧你自己那点德性吧。说你没素质你还不承认。
我尊重自己的母亲和天下所有的母亲,包括畜生的母亲。所以我不想回敬你。
py330316117 2010-03-27
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 bayougeng 的回复:]

引用 8 楼 py330316117 的回复:

while ((n = buffer.read(b, 0, 1366)) != -1)
在while中给n赋值

你是在和我搞笑吗,这个是判定语句,到你这就成了赋值语句,你可真牛b,回去好好看看buffer这个地方的书吧

哇,好牛B也。
麻烦您看清楚:
n = buffer.read(b, 0, 1366) 赋值
作为一个表……
[/Quote]
没你牛b 你去开帖子吧,我什么也没说就弄个我没素质,caonima才叫美素质,什么人,说你2局就给我弄个没素质,你有素质你怎么不闭嘴哪
py330316117 2010-03-26
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 bayougeng 的回复:]

2楼你肯定没仔细看代码。
楼主你的while循环中没有关于越界的判断,也就是说,你总是假设你的缓冲区能装下整个文件。
这显然是不现实的。你应该加入清理缓冲区的操作。
你的debug信息看起来已经很清楚了,告诉你超过了缓冲区的大小。
[/Quote]
你仔细看了,哪你告诉我他们的值都是什么
bawgiitx 2010-03-26
  • 打赏
  • 举报
回复
解决了,谢谢大家了
con.setRequestProperty("Range", "bytes="+start+"-"+end);
请求从start开始到end(Bybe)段文件内容
调试时缓冲区每次刚刚好多出一Byte
最后查出是end没有减一
bayougeng 2010-03-26
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 py330316117 的回复:]

while ((n = buffer.read(b, 0, 1366)) != -1)
在while中给n赋值

你是在和我搞笑吗,这个是判定语句,到你这就成了赋值语句,你可真牛b,回去好好看看buffer这个地方的书吧
[/Quote]
哇,好牛B也。
麻烦您看清楚:
n = buffer.read(b, 0, 1366) 赋值
作为一个表达式,它也是有值的,它的值,就是buffer.read(b, 0, 1366)的返回值,也就是n。
所以说有了这样的写法;
(n = buffer.read(b, 0, 1366)) != -1
在赋值的同时做判断。
流读取常用的格式,明白?
如果还不服气,单独开贴让大家评理。
另外,我觉得你很没素质,真的。
py330316117 2010-03-26
  • 打赏
  • 举报
回复
while ((n = buffer.read(b, 0, 1366)) != -1)
在while中给n赋值


你是在和我搞笑吗,这个是判定语句,到你这就成了赋值语句,你可真牛b,回去好好看看buffer这个地方的书吧
Ark032425 2010-03-26
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 qybao 的回复:]
System.arraycopy(b, 0, buff, st, n);//很明显,如果st+n>buff.length,那就数组越界了


Java code

if (st+n > buff.length) {
if (st < buff.length) {
System.arraycopy(b, 0, buff, st, buff.length-st);……
[/Quote]
要事先判断
bayougeng 2010-03-26
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 py330316117 的回复:]

引用 3 楼 bayougeng 的回复:

2楼你肯定没仔细看代码。
楼主你的while循环中没有关于越界的判断,也就是说,你总是假设你的缓冲区能装下整个文件。
这显然是不现实的。你应该加入清理缓冲区的操作。
你的debug信息看起来已经很清楚了,告诉你超过了缓冲区的大小。

你仔细看了,哪你告诉我他们的值都是什么
[/Quote]
while ((n = buffer.read(b, 0, 1366)) != -1) {
try{
System.arraycopy(b, 0, buff, st, n);
} catch (Exception ee) {//13987
System.out.println(Thread.currentThread() + "st:" + st + ",n:" + n);
System.out.println((1366*1024 -st)+" "+ee.toString());
}
synchronized (ITHIS) {
down_len += n;
}
st += n;
}
在while中给n赋值,每次循环体结束后重置st。
buff是缓冲区,在while的括号中进行填充。
qybao 2010-03-25
  • 打赏
  • 举报
回复
System.arraycopy(b, 0, buff, st, n);//很明显,如果st+n>buff.length,那就数组越界了


if (st+n > buff.length) {
if (st < buff.length) {
System.arraycopy(b, 0, buff, st, buff.length-st);
}
System.out.printf("overflow:%d\n", st+n-buff.length);
} else {
System.arraycopy(b, 0, buff, st, buff.length-st);
}
bayougeng 2010-03-25
  • 打赏
  • 举报
回复
2楼你肯定没仔细看代码。
楼主你的while循环中没有关于越界的判断,也就是说,你总是假设你的缓冲区能装下整个文件。
这显然是不现实的。你应该加入清理缓冲区的操作。
你的debug信息看起来已经很清楚了,告诉你超过了缓冲区的大小。
py330316117 2010-03-25
  • 打赏
  • 举报
回复
byte[] b = new byte[1366];
n = 0;
st = 0;
System.arraycopy(b, 0, buff, st, n);
以上是我从你代码中找到的变量和方法,全是0和null没有值你怎么调用copy方法
amos1989 2010-03-25
  • 打赏
  • 举报
回复
错误提示列???

62,621

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧