2012-03-14 29 views
1

我想编写一个方法,从文件中读取部分字节数组。 为此,我正在使用fileinputstream和缓冲输入流。Java BufferedInputStream.read()IndexOutOfBounds

这样的:

fis = new FileInputStream(file); 
bis = new BufferedInputStream(fis); 
dis = new DataInputStream(bis); 

我通过调用一个方法名 “的OpenFile(字符串文件)” 做一次。 一旦文件已被打开与该方法中,我尝试与功能操作:“ReadParts(字节[]缓冲器,诠释抵消,诠释LEN)”

dis.read(buffer, offset, len);    
for(int i = 0; i < buffer.length; i++) System.out.print((char)buffer[i]); 

// used data: 
// file = "C:\Temp\test.txt" with a size of 949 
// buffer: always in this case with a size of 237, except for the last one its 238 
// offsets: 0, 237, 474, 711 
// len is always 237, except for the last one its 238 

线dis.read()后抛出第一步总是一个indexOutOfBounds错误消息,但我无法弄清楚为什么和什么。使用netbeans调试器没有帮助,因为我找不到索引的问题.....

+0

请张贴在那里你计算偏移代码和len并在您初始化缓冲区。这很可能会导致你的问题。 – AlexS 2012-03-14 11:51:36

回答

0

如果你读了流进缓冲器阵列,您offset和len永远必须是:

offset = 0; 
len = buffer.length(); 

这些参数指定的数据放在缓冲区,不将数据从读流。该流是连续阅读(或者这是拼写?)!

如果你总是叫:

buffer = new byte[256]; 
dis.read(buffer, 0, 256); 

会发生这种情况: 第一呼叫Streamposition(被返回的下一个字节的位置)之前为0

  1. Streamposition电话后= 256和缓冲区包含字节0-255
  2. 调用后的串流位置= 512且缓冲区包含字节256-511
  3. ...

    dis.reset();

串流位置再次为0。

此代码从流中读取只有256-511字节到缓冲区:

byte[] buffer = new byte[512]; 
dis.skip(256); 
dis.read(buffer, 0, 256); 

看到,最后256个字节的缓冲区都没有填写。这是read(byte [],int,int)和read(byte [])之间的区别之一!

下面为大家介绍一些链接,描述一个流的概念,并读取方法的用法: read() Streams

+0

那么为什么然后使用read(byte,off,len)函数呢? read(byte [])会做同样的工作 - > offset = 0和len = byte.length。这意味着它读取整个文件。 我的计划是从文件中读取零件而不是整个文件。再次,我计划(在这个例子中)从237读到474.这是236字节。所以如果缓冲区长度为237就足够了。我只是没有获得偏移量(这是> = 0)和偏移量+ len(用于缓冲区大小)之间的连接.... – 2012-03-14 11:58:29

+0

如果您想要将读取字节放入,请使用read(byte,offset,len)缓冲区中的特殊位置。如果你只想从流中读取一些而不是全部字节,你必须使用skip()。如果在流中使用带绝对偏移量的跳过,则必须先调用reset(),如果之前从此流中读取了某些内容。 – AlexS 2012-03-14 12:08:03

+0

我刚刚这样做是为了跳过空字节: for(int i = 0; i 2012-03-14 12:13:30

1

你是怎么想出offset和len。我现在的猜测是你偏移+ len大于缓冲区。

+0

好,这里是我现在不明白的问题吗?关于文档:dis.read(b,off,len): b - 读取数据的缓冲区。 off - 数据的起始偏移量。 len - 读取的最大字节数。 所以我必须改变缓冲区,以获得字节238到474? (在这种情况下237比1足够多了!!) – 2012-03-14 11:43:31

0

偏移量是缓冲区而不是文件的偏移量。

我怀疑你想要的是

byte[] buffer = new byte[237]; 

int len = dis.read(buffer); // read another 237 bytes. 

if (len < 0) throw new EOFException(); // no more data. 
for(int i = 0; i < len; i++) 
    System.out.print((char)buffer[i]); 
// or 
System.out.print(new String(buffer, 0, 0, len)); 

在调试器,您可以检查偏移> = 0和偏移+ lengh < = buffer.length?

从InputStream.read()

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(); 

其中一个检查是无效的条件。

+0

偏移量是237,而len也是237。所以bufferlengh是237.是不是它计数在lennum的offsetnum从237?该例外不包含详细信息,或者我不能提取详细信息...:/(当我使用ex.getCause()我会得到一个nullpointerexception) – 2012-03-14 11:37:25

+0

说,我必须提高缓冲区,即使我只想在第二步中读取237个字节(文件中的237到474个)需要一个加倍的缓冲区?对? – 2012-03-14 11:47:27

+0

不,请参阅我的帖子。你滥用抵消和len。 – AlexS 2012-03-14 11:55:58

0

你会得到IndexOutOfBoundsException - 如果

  • offset为负,

  • len为负,

  • len大于buffer.length更大 - 关

第3点的示例:

如果有500个字符或输入文件1500个字符,下面的程序将运行成功,

byte[] buffer = new byte[1000]; 
int offset = 0; 
int len = 1000; 
dis.read(buffer, offset, len);    
for(int i = 0; i < buffer.length; i++) System.out.print((char)buffer[i]); 

但它会失败,并抛出异常,如果,

byte[] buffer = new byte[1000]; 
int offset = 0; 
int len = 1001; 
dis.read(buffer, offset, len); 
for(int i = 0; i < buffer.length; i++) System.out.print((char)buffer[i]); 

检查的价值在这两种情况下的长度。

+0

是的,但这意味着我需要一个更大的缓冲区,如果我想从字节237读到474,即使是“真实”的字节大小也是236? – 2012-03-14 11:50:31