Java 阅读url内容

Java 阅读url内容,java,Java,我想按字节读取url内容。我必须从url的内容中读取64 kb 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);

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

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) {}
        }
    }

}
上述编码用于按字符读取


我需要读取字节。

如果删除对字符的强制转换,则有一个字节

如果要将整个内容存储到内存中,可以使用
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

即可直接从返回的InputStream对象读取:

  InputStream istream = urlc.getInputStream(); 

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

  istream.close(); 
我就是这样做的

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

就像波佐说的,你已经在读字节了。但是,将所有内容读入字节数组可能比一次读入一个字节更有效

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) {}
     }
  }

我正在添加一个单独的答案,因为我突然意识到这个问题可以用另一种方式来解释:我认为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[],这样就可以将它们打印为字符串

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

要将URL的前64KB放入
字节[]

这很简单:

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 = new String(first64kb);
但是,这将考虑平台默认编码。您希望为此使用服务器端指定的编码,该编码在响应头中可用

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);
另见


你在问什么?方法
java.io.InputStream.read()
正在从流中读取一个
字节。如果您从未实例化StrinngBuilder,那么当您首次尝试使用它时,将得到一个NullPointerException。其次,您不能调用append(byte[])并期望发生任何有用的事情。您说您想以字节为单位进行读取,但似乎在说了所有的话和做了所有的事之后,您正试图获取一个字符串。您试图读入的是二进制数据还是字符数据?我假设构建器是一个StringBuilder,因此向其中写入int只会将其附加到一个数字字符串序列中。我只是更新我的问题程序。但我在运行程序时遇到了错误。@Bozho-这是一个好问题,但我回答的问题是如何读取字节,而不是字符-然而,我还是犯了错误,因为InputStream和BufferedInputStream都读取字节。我想我现在知道OP想要什么了-请看下面的单独答案。谢谢你的重播,是的,我知道这一点,但我只想从内容中读取64kb。有什么可能吗?我可以大胆地猜测你为什么会出现错误(太阳黑子活动),但是如果你让我们知道你的确切错误是什么,那么就更容易诊断了。