【问题标题】:Load image from URL and limit the size of the file从 URL 加载图像并限制文件大小
【发布时间】:2011-12-14 16:02:14
【问题描述】:

我在 SO 上找到了如何使用这个问题从 Url 加载图像:how to load a image from web in java

但我想限制正在加载的文件的大小,因为所有答案都有一个共同点:如果用户将 url 提供给 1 TB 文件,它将使我的服务器崩溃:/

如何限制正在下载的文件的大小?

感谢您的帮助! :)

【问题讨论】:

  • “如果用户将 url 提供给 1 TB 的文件,它会导致我的服务器崩溃” 为什么它会导致您的服务器崩溃?资源是否来自来自您的服务器?您的服务器是否充当文件的代理(从另一台服务器获取)?

标签: java image url download


【解决方案1】:

按照您从上一个答案中获得的代码...

URL url = new URL("http://host/theimage.jpg");
URLConnection conn = new URLConnection(url);

// now you get the content length
int cLength = conn.getContentLength();

InputStream in = conn.getInputStream();

你可以在这里找到更多关于URLConnection()的方法。

请注意,这只会尊重另一端给出的 HTTP 标头,它没有理由遵守或诚实。因此,如果您在真正安全且“请勿攻击我”方面进行游戏,您应该检查即将到来的InputStream,并在达到固定数据量后终止它。

【讨论】:

  • 下载前给出的内容长度? (在标题中)?
  • 顺便说一句,我得到一个“无法实例化类型 URLConnection”:/
  • @cx42net 通常在前面给出内容长度。例如,当您使用浏览器(一个大文件)下载文件时,它可以为您提供剩余百分比(通常估计完成时间)或不。如果它确实给了你这些数字,那是因为另一端的连接已经接受了 HTTP 标头并在标头上发送了长度。
  • @Jack Edmonds 竭尽全力为您提供我所说的偏执解决方案。
  • 也许您的意思是检查内容长度是否小于@cx42net 想要读取的最大字节数(例如if (cLength>1000000000000)throw new FileTooBigException();)?
【解决方案2】:

如果你想保证你不会下载超过一定数量,你需要用你自己的实现包裹InputStream。本质上是创建一个新类

/**
 * Limits the amount of data you can read.
 * Warning: this only partially implements all the necessary methods.
 *     You will need to implement the rest that I was too lazy to include.
 */
public class InputStreamLimiter extends InputStream {
    private final InputStream wrappedInputStream;
    private int bytesRead;
    private final maxBytes;
    public InputStreamLimiter(final InputStream stream, final int maxBytes)
    {
        this.maxBytes=maxBytes;
        this.wrappedInputStream=stream;
    }
    public int available(){return wrappedInputStream.available();}
    public void close(){wrappedInputStream.close();}
    //Continue wrapping methods until you reach the read() methods.

    /**
     * Provide your own implementation of the read methods that make sure you don't attempt to read too many bytes.
     * This method crashes if you attempt to read too much.
     */
    public int read(final byte b[]) throws IOException {
        if (b.length + bytesRead > maxBytes) throw new IOException("File was too big.");
        else return wrappedInputStream.read(b);
    }
}

然后像这样使用那个类:

ImageIO.read(new InputStreamLimiter(new URL("http://server/image.png").openStream(),MAX_BYTES)));

【讨论】:

  • 你的答案真的很棒也很有趣,如果我可以选择两个答案,我们的答案会在,但不幸的是,接受的一个更适合我现在的需求(也许我以后会用你的) .再次感谢:)
【解决方案3】:

保证您不会下载大文件的更简单方法是使用IOUTils.read

    int maxDownload = 1024*1024*2;
    URL website = new URL("http://www.wswd.net/testdownloadfiles/200MB.zip");

    byte[] outBytes = new byte[maxDownload];
    InputStream stream = website.openStream();

    IOUtils.read(stream, outBytes, 0, maxDownload);

    if (stream.read() != -1) {
        System.out.println("File too big");
    } 

    IOUtils.write(outBytes, new FileOutputStream("200MB.zip"));

【讨论】:

    【解决方案4】:

    我认为您可以在 InputStream 上使用“标记”方法并设置 readlimit。

    【讨论】:

      猜你喜欢
      • 2021-05-15
      • 1970-01-01
      • 1970-01-01
      • 2017-09-02
      • 2015-02-18
      • 2020-11-07
      • 2016-06-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多