2010-06-18 338 views
0

我想按字节读取url内容。我必须从url的内容中读取64 kb。阅读url内容

public void readUrlBytes(String address) { 
    StringBuilder builder = null; 
    BufferedInputStream input = null; 
    byte[] buffer = new byte[1024]; 
    int i = 0; 
    try { 
     URL url = new URL(address); 
     URLConnection urlc = url.openConnection(); 
     input = new BufferedInputStream(urlc.getInputStream()); 
     int bytesRead; 
     while ((bytesRead = input.read(buffer)) != -1) { 
      builder.append(bytesRead); 
      if (i==64) { 
       break; 
      } 
      i++; 
     } 
     System.out.println(builder.toString()); 
    } catch (IOException l_exception) { 
     //handle or throw this 
    } finally { 
     if (input != null) { 
      try { 
       input.close(); 
      } catch(IOException igored) {} 
     } 
    } 

} 

上面的代码是用于读字符明智的。

我需要读取字节。

+0

什么是你问? java.io.InputStream.read()方法从流中读取一个“byte”。 – 2010-06-18 14:55:53

+0

好的,在查看粘贴的新代码后,还有其他一些问题。 你永远不会实例化StrinngBuilder,当你第一次尝试使用它时,你会得到一个NullPointerException。其次,你不能调用append(byte [])并期望有用的事情发生。你说你想读取字节数,但看起来你试图在所有事情说完之后得到一个字符串。您想要读取的是二进制文件还是字符数据? – 2010-06-18 15:56:13

回答

0

如果您将转换删除到char,您有一个字节。

如果您打算将整个内容存储到内存中,则可以使用ByteArrayOutputStream并将每个字节写入它。最后调用toByteArray()获得的字节数组:

ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
while ((byteRead = buffer.read()) != -1) { 
    baos.write(byteRead); 
} 

byte[] result = baos.toByteArray(); 

更新:你提到你想只有64 KB。为了实现这一目标只是检查baos.size()是否已达到64 * 1024和break

0

你可以简单地从InputStream对象直接读取返回:

InputStream istream = urlc.getInputStream(); 

    int byteRead; 
    while ((byteRead = istream.read()) != -1) 
    builder.append(byteRead); 

    istream.close(); 
+0

我假设这个构建器是一个StringBuilder,所以编写一个int就可以将它附加到一串字符串中。 – Bozho 2010-06-18 14:59:12

+0

我只是更新我的问题程序。 但我运行程序时出错。 – 2010-06-18 15:22:47

+0

@Bozho - 好点,但我回答的问题是如何读取字节,而不是字符 - 但是,无论如何,因为InputStream和BufferedInputStream都读取字节,我想我现在知道OP想要什么 - 请参阅下面的单独答案。 – JTeagle 2010-06-18 19:41:30

0

这是我做到了,

    input = urlc.getInputStream(); 
        byte[] buffer = new byte[4096]; 
        int n = - 1; 

        ByteArrayOutputStream baos = new ByteArrayOutputStream(4096); 

        while ((n = input.read(buffer)) != -1) 
        { 
          if (n > 0) 
          { 
            baos.write(buffer, 0, n); 
          } 
        } 
        byte[] bytes = baos.toByteArray(); 
1

Bozho说,你已经在阅读字节。但是,将所有内容读入字节数组可能更有效,而不是一次只写一个字节。

BufferedInputStream input = null; 
    byte[] buffer = new byte[4096]; 
    try { 
    URLConnection urlc = url.openConnection(); 
    input= new BufferedInputStream(urlc.getInputStream()); 
    int bytesRead; 
    while((bytesRead = input.read(buffer)) != -1) 
    { 
     //do something with the bytes, array has data 0 to bytesRead (exclusive) 
    } 
    } 
    catch(IOException l_exception) { 
     //handle or throw this 
    } 
    finally { 
    if (input != null) { 
     try { 
      input.close(); 
     } 
     catch(IOException igored) {} 
    } 
    } 
+0

感谢您的重播,雅,我知道这一点, 但我想从内容只读64kb。 有没有可能? – 2010-06-18 15:12:39

+0

我只是更新我的程序,但我得到错误。 为什么? – 2010-06-18 15:26:37

+2

我可以大胆猜测为什么你会得到一个错误(太阳黑子活动),但是如果你让我们知道你得到的确切错误会更容易诊断。 – 2010-06-18 15:43:11

0

我加入一个单独的答案,因为我突然意识到另一种方式的问题可以解释:我觉得OP要转换表示字符的特定字符的内部格式的字节设置成流相应的字符。例如,将ASCII码转换为ASCII字符。

这不是一个完整的答案,但希望将OP放在正确的轨道上,如果我理解正确。我使用的是UTF-8来作为例子:

BufferedInputStream istream = new BufferedInputStream(urlc.getInputStream()); 
int numBytesAvailable = istream.available(); 
byte[] buffer = new byte[numBytesAvailable]; 
istream.read(buffer); 

ByteBuffer tempBuffer = ByteBuffer.wrap(buffer); 
Charset utf8Chars = Charset.forName("UTF-8"); 
CharBuffer chars = utf8Chars.decode(tempBuffer); 

现在你有字符的缓冲如Java看到他们(你可以使用chars.array()来得到一个char []出来的),所以他们可以打印为一个字符串。

警告:在尝试解码之前,您需要将整个流读入字节缓冲区;当您不知道字符内部字节序列的正确结尾时将解码缓冲区将导致字符错误!

0

您想将第一个从网址64KB转换为byte[]

这很简单:

public byte[] getFirst64KbFromUrl(String address) throws IOException { 
    InputStream input = null; 
    byte[] first64kb = new byte[64 * 1024]; 
    try { 
     input = new URL(address).openStream(); 
     input.read(first64kb); 
    } finally { 
     if (input != null) try { input.close(); } catch(IOException ignore) {} 
    } 
    return first64kb; 
} 

如果实际上与转换的字节String一个问题,这里是你如何能做到这一点:

String string = new String(first64kb); 

但是这需要平台默认的编码考虑到。你想使用Content-Type响应头中提供的服务器端指定的编码。

URLConnection connection = new URL(address).openConnection(); 
// ... 
String contentType = connection.getHeaderField("Content-Type"); 
String charset = "UTF-8"; // Let's default it to UTF-8. 
for (String param : contentType.replace(" ", "").split(";")) { 
    if (param.startsWith("charset=")) { 
     charset = param.split("=", 2)[1]; 
     break; 
    } 
} 
// ... 
String string = new String(first64kb, charset); 

参见: