有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

二进制文件上的socketJava http请求无法读取正确的内容长度

我正在发送一个http请求以获取二进制文件(这里我正在尝试一个图像)

public class Main {

    public static void main(String[] args) throws UnknownHostException,
            IOException {
        new Main(args);

    }

    public Main(String[] args) throws UnknownHostException, IOException {
        lance(args);
    }

    private void lance(String[] args) throws UnknownHostException, IOException {
        Lanceur lan = new Lanceur("www.cril.univ-artois.fr", "/IMG/arton451.jpg");
        lan.requete();
    }

}

public class Lanceur {

    Socket s;
    InputStream readStream;
    OutputStream writeStream;
    String host;
    String ressource;

    public Lanceur(String host, String ressource) throws UnknownHostException,
            IOException {
        s = new Socket(InetAddress.getByName(host), 80);
        readStream = s.getInputStream();
        writeStream = s.getOutputStream();
        this.host = host;
        this.ressource = ressource;
    }

    public void requete() throws IOException {
        // String[] length = null;
        writeStream.write(new String("GET " + ressource + " HTTP/1.1\r\n"
                + "Host: www.google.com\r\n" + "\r\n").getBytes());
        writeStream.flush();
        AnswerReader as = new AnswerReader(readStream);
        as.read();
        as.writeFile(this.ressource);
        s.close();
    }
}

public class AnswerReader {
    BufferedReader br;
    DataInputStream dis;
    String status;
    Map<String, String> attrs;
    byte[] content;

    public AnswerReader(InputStream is) {
        br = new BufferedReader(new InputStreamReader(is));
        dis = new DataInputStream(new BufferedInputStream(is));
    }

    public void read() throws NumberFormatException {
        readStatus();
        try {
            readAttrs();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        String contentL = attrs.get("Content-Length");

        readContent(Integer.valueOf(contentL));

    }

    public void readStatus() {
        try {
            status = br.readLine();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    public void readAttrs() throws IOException {
        attrs = new HashMap<String, String>();
        String line;

        for (line = br.readLine(); line.length() > 0; line = br.readLine()) {
            int index = line.indexOf(':');
            attrs.put(line.substring(0, index), line.substring(index + 2));
        }
    }

    private void readContent(int size) {

        this.content = new byte[size];
        byte[] buff = new byte[1024];
        int copied = 0;
        int read = 0;
        while (copied < size) {
            try {
                read = dis.read(buff);
                if (read == -1)
                    break;
            } catch (IOException e) {
                e.printStackTrace();
            }
            // byte[] byteArray = new String(buff).getBytes();
            System.arraycopy(buff, 0, content, copied, read);
            copied += read;
        }
        System.out.println(copied + "///" + size);
    }

    public void writeFile(String name) throws IOException {
        String tab[] = name.split("/");
        String filename = tab[tab.length - 1];
        FileOutputStream fos = new FileOutputStream("./" + filename);
        fos.write(content);
        fos.flush();
        fos.close();
    }
}

问题来自readContent()。内容长度很好,但它不会读取所有数据。从这个例子可以看出:

22325///38125

共 (1) 个答案

  1. # 1 楼答案

    {}正在缓冲一些二进制数据。您必须找到另一种方法来使用无缓冲输入流来读取标题行,例如DataInputStream.readLine()、deprecation或no

    但是你应该使用HttpURLConnection。这更容易