我将类打成jar包将资源也放到jar包中的res目录下.
我用方式一读取文件能够正常把整个文件读入数组 b 中
方式一:
InputStream is = this.getClass().getResourceAsStream("/res/a.jpg");
byte[] b = new byte[is.available()];
for(;is.available()>0;i++){
b[i] = (byte)is.read();
}
ImagIcon image = new ImageIcon(b);
用方式二读取文件只能将文件的前一部分读入数组 b 中导致创建ImageIcon时出错
方式二:
InputStream is = this.getClass().getResourceAsStream("/res/a.jpg");
byte[] b = new byte[is.available()];
is.read(b);
ImagIcon image = new ImageIcon(b);我看到有人说不能用getResourceAsStream()方法读取jar包中的数据不知道这种说法正确吗?当然用这种方式一和这个 ImageIcon image = new ImageIcon(this.getClass().getResource("/res/a.png"));能够正常运行.有没有人遇到从jar包中读取资源的问题?
方式二为什么只能读取前一部分数据到数组中呢?
我用方式一读取文件能够正常把整个文件读入数组 b 中
方式一:
InputStream is = this.getClass().getResourceAsStream("/res/a.jpg");
byte[] b = new byte[is.available()];
for(;is.available()>0;i++){
b[i] = (byte)is.read();
}
ImagIcon image = new ImageIcon(b);
用方式二读取文件只能将文件的前一部分读入数组 b 中导致创建ImageIcon时出错
方式二:
InputStream is = this.getClass().getResourceAsStream("/res/a.jpg");
byte[] b = new byte[is.available()];
is.read(b);
ImagIcon image = new ImageIcon(b);我看到有人说不能用getResourceAsStream()方法读取jar包中的数据不知道这种说法正确吗?当然用这种方式一和这个 ImageIcon image = new ImageIcon(this.getClass().getResource("/res/a.png"));能够正常运行.有没有人遇到从jar包中读取资源的问题?
方式二为什么只能读取前一部分数据到数组中呢?
你这个问题,getResourceAsStream()方法 倒是没碰到过!有空 测试一下!
关于JAR,读取应该问题不大,但不知道能不能通过程序 往JAR里添加内容!
从输入流中读取一定数量的字节并将其存储在缓冲区数组 b 中,所以不是一次就读买整个数组b,通常需要循环来(正如你方法一)直到文件尾
返回此输入流方法的下一个调用方可以不受阻塞地从此输入流读取(或跳过)的字节数。这个方法不一定返回流所包含的所有字节,可能只是一部分,其实流在读取的过程中是不能获取到大小的.要正确读取全部的字节应该用循环读取,直到读取不到值为止
System.out.println("文件大小:"+is.available());
byte[] b = new byte[is.available()];
int i = 0;
for(;is.available()>0;i++){
int m = is.read();
b[i] = (byte) m;
}
System.out.println("用For循环读取字节数为: "+i);
is = this.getClass().getResourceAsStream("/res/a.jpg");
System.out.println("文件大小:"+is.available());
b = new byte[is.available()];
i = is.read(b);
System.out.println("用read共读取字节数为: "+i);
加入了输出大家看一下如果不打jar包直接运行输出为:
文件大小:27446
用For循环读取字节数为: 27446
文件大小:27446
用read共读取字节数为: 27446打成jar包 通过java -jar 运行输出为:
文件大小:27446
用For循环读取字节数为: 27446
文件大小:27446
用read共读取字节数为: 8497所以这个不是is.available()的问题.查看了InputStream的api和源码都没弄明白这个问题.看这个源码也是一个一个读的呀?
public int read(byte b[], int off, int len) throws IOException {
if (b == null) {
throw new NullPointerException();
} else if (off < 0 || len < 0 || len > b.length - off) {
throw new IndexOutOfBoundsException();
} else if (len == 0) {
return 0;
} int c = read();
if (c == -1) {
return -1;
}
b[off] = (byte)c; int i = 1;
try {
for (; i < len ; i++) {
c = read(); //循环读取
if (c == -1) {
break;
}
b[off + i] = (byte)c;
}
} catch (IOException ee) { //估计是这里有异常抛出
}
return i;
}
返回此输入流方法的下一个调用方可以不受阻塞地从此输入流读取(或跳过)的字节数。 这个方法不一定返回流所包含的所有字节,可能只是一部分,其实流在读取的过程中是不能获取到大小的.要正确读取全部的字节应该用循环读取,直到读取不到值为止
Returns an estimate of the number of bytes that can be read (or skipped over) from this input stream without blocking by the next invocation of a method for this input stream.
不是其值不是文件的大小
而inputstream中的read()方法都是盡量方法,不保證是會一次讀滿整個buf的,你給出的源代碼就是證明
byte[] bs = new byte[1024];
int len;
while((len = is.read(bs))!=-1){
....我更推荐这样读取Stream的数据,自己控制缓冲区
for(;is.available()>0;i++){
int m = is.read();
b[i] = (byte) m;
}
2、根据我发的read(byte[],int,int)的源代码
public int read(byte b[], int off, int len) throws IOException {
if (b == null) {
throw new NullPointerException();
} else if (off < 0 || len < 0 || len > b.length - off) {
throw new IndexOutOfBoundsException();
} else if (len == 0) {
return 0;
} int c = read();
if (c == -1) {
return -1;
}
b[off] = (byte)c; int i = 1;
try {
for (; i < len ; i++) {
c = read(); //循环读取
if (c == -1) {
break;
}
b[off + i] = (byte)c;
}
} catch (IOException ee) { //估计是这里有异常抛出
}
return i;
}
这里面也是用循环读取的,所以我调用这个方法应该返回和我自己用for循环读取一样的结果.
但是返回的比我用for循环读取的要少请看下面的例子 我把大家有争议的available()方法去了. InputStream is = this.getClass().getResourceAsStream("/res/a.jpg");
System.out.println("文件大小/is.available():"+is.available());
int length = 30000;
byte[] b = new byte[length];
int i = 0;
for(;is.available()>0;i++){
int m = is.read();
b[i] = (byte) m;
}
System.out.println("用For循环读取字节数为: "+i);
System.out.println("--------用read(byte[])方法读取-------------------");
is = this.getClass().getResourceAsStream("/res/a.jpg");
b = new byte[length];
i = is.read(b);
System.out.println("用read共读取字节数为: "+i);
System.out.println("--------用read(byte[],int,int)方法读取-----------");
is = this.getClass().getResourceAsStream("/res/a.jpg");
BufferedInputStream bis = new BufferedInputStream(is); b = new byte[length];
i = bis.read(b,0,b.length);
System.out.println("用read(b,int,int)共读取字节数为: "+i);
这个不打jar包输出的结果为:文件大小/is.available():27446
用For循环读取字节数为: 27446
--------用read(byte[])方法读取-------------------
用read共读取字节数为: 27446
--------用read(byte[],int,int)方法读取-----------
用read(b,int,int)共读取字节数为: 27446打成jar包后运行输出的结果为:文件大小/is.available():27446
用For循环读取字节数为: 27446
--------用read(byte[])方法读取-------------------
用read共读取字节数为: 8497
--------用read(byte[],int,int)方法读取-----------
用read(b,int,int)共读取字节数为: 27446看这个结果奇怪吧!!!read(byte[]) 调用的就是 read(byte[],int,int) 而我自己调用返回的结果却不同?
各位再关注一下.
你为何还在用这个方法,我无语你应该用返回值判断是否结束,而不是依赖于 available至于为什么?自己去看API的说明吧。if (c == -1) {
break;
} 这是jdk里面判断是否读取结束的方法,你自己看
for(;is.available()>0;i++){ 这个只是一个例子当时随便写的 我只是把后面两种方法的available方法去掉了.我改成这样:
int i= 0;
int c = -1;
while((c = is.read())!=-1){
b[i++] = (byte)c;
}后面的结果也不对呀?
InputStream is = this.getClass().getResourceAsStream("/res/a.jpg");
System.out.println("文件大小/is.available():"+is.available());
int length = 30000;
byte[] b = new byte[length];
int i = 0;
int c = -1;
while((c = is.read())!=-1){ //只是例子没有优化.
b[i++] = (byte)c;
}
System.out.println("用while循环读取字节数为: "+i);
//文件大小/is.available():27446
//用while循环读取字节数为: 27446
System.out.println("\n--------用read(byte[])方法读取-------------------");
is = this.getClass().getResourceAsStream("/res/a.jpg");
//-------------------重点看这里!!!!!----------------
b = new byte[length];
i = is.read(b);
System.out.println("用read共读取字节数为: "+i); //--------用read(byte[])方法读取-------------------
//用read共读取字节数为: 8497 System.out.println("\n--------用read(byte[],int,int)方法读取-----------");
is = this.getClass().getResourceAsStream("/res/a.jpg");
BufferedInputStream bis = new BufferedInputStream(is);
//-------------------重点看这里!!!!!----------------
b = new byte[length];
i = bis.read(b,0,b.length);
System.out.println("用read(b,int,int)共读取字节数为: "+i); //--------用read(byte[],int,int)方法读取-----------
//用read(b,int,int)共读取字节数为: 27446
重点看后面两个例子的输出read(byte[]) 方法是调用的return read(b, 0, b.length)这个但是这两个方法的输出为什么不同?
一个输出的是
--------用read(byte[])方法读取-------------------
用read共读取字节数为: 8497另一个输出的是--------用read(byte[],int,int)方法读取-----------
用read(b,int,int)共读取字节数为: 27446
不用再关注available了 呵呵.
int i = 0;
int c = -1;
while((c = is.read())!=-1){//不考虑性能等其它事情.
b[i++] = (byte)c;
}
System.out.println("用while循环读取字节数为: "+i);
//文件大小/is.available():27446
//用while循环读取字节数为: 27446 System.out.println("\n--------用read(byte[])方法读取-------------------");
is = this.getClass().getResourceAsStream("/res/a.jpg");
b = new byte[length];
i = is.read(b);
System.out.println("用read共读取字节数为: "+i);
//--------用read(byte[])方法读取-------------------
//用read共读取字节数为: 8497while循环和read(byte[])方法内部类似吧?
为什么while可以读取的27446,而read(byte[]) 只可以读取8497不用再关注available了 呵呵.
发现InputStream.read(byte[]) 就是有问题.
但是不知道是那里的问题.
an array of bytes. An attempt is made to read as many as
len bytes, but a smaller number may be read.
The number of bytes actually read is returned as an integer.它没有保证读得跟你要求的len一样长
它只不过尝试attempt 读得跟len一样长
你还是得关注实际读的长度actually read
你的情况是读到中途的时候就出现IO异常了。该方法也说了,建议子类提供此方法更为有效的实现,
所以不建议直接来用这个方法。