我正在尝试从Squeak下载文件到磁盘。
我的方法对小文本/html文件很有效,
但由于缺乏缓冲,
对于大型二进制文件来说非常慢
https://mirror.racket-lang.org/installers/6.12/racket-6.12-x86_64-win32.exe
而且,完成后,文件要大得多(113MB)
比下载页(75MB)显示的要多。
我的代码如下:

download: anURL
    "download a file over HTTP and save it to disk under a name extracted from url."
    | ios name |
    name := ((anURL findTokens: '/') removeLast findTokens: '?') removeFirst.
    ios := FileStream oldFileNamed: name.
    ios  nextPutAll: ((HTTPClient httpGetDocument: anURL) content).
    ios close.
    Transcript show: 'done'; cr.

我尝试过使用[bytes = stream next bufSize. bytes printTo: ios]循环对http响应的contentStream中的固定大小的块进行[stream atEnd] whileFalse:处理,但这会使输出文件在每个块周围加上单引号,并在块之后加上额外的内容,看起来像流的所有字符,每个单引号。
如何实现对磁盘文件的http响应的缓冲写入?
另外,有没有办法在Squeak中显示下载进度?

最佳答案

正如leandro已经写的那样,这个问题与#binary有关。
你的代码几乎是正确的,我已经冒昧地运行了它-现在它正确地下载了整个文件:

| ios name anURL |
anURL := ' https://mirror.racket-lang.org/installers/6.12/racket-6.12-x86_64-win32.exe'.
name := ((anURL findTokens: '/') removeLast findTokens: '?') removeFirst.
ios := FileStream newFileNamed: 'C:\Users\user\Downloads\_squeak\', name.
ios binary.
ios  nextPutAll: ((HTTPClient httpGetDocument: anURL) content).
ios close.
Transcript show: 'done'; cr.

至于冻结,我认为问题在于你下载时整个环境只有一个线程。这意味着在你下载整个文件之前,你将无法使用Squeak。
刚刚在pharo中测试过(更容易安装),下面的代码可以按照您的需要工作:
ZnClient new
  url: 'https://mirror.racket-lang.org/installers/6.12/racket-6.12-x86_64-win32.exe';
  downloadTo: 'C:\Users\user\Downloads\_squeak'.

关于http - 在Squeak中,将大HTTP响应的大块一到达就写入磁盘,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/49400491/

10-11 08:43