|
3 | 3 | import posixpath |
4 | 4 | from typing import TYPE_CHECKING, Any, BinaryIO, Callable, Dict, Optional, Tuple |
5 | 5 |
|
| 6 | +from fsspec.callbacks import _DEFAULT_CALLBACK |
6 | 7 | from fsspec.spec import AbstractFileSystem |
| 8 | +from fsspec.utils import isfilelike |
7 | 9 |
|
8 | 10 | if TYPE_CHECKING: |
9 | 11 | from io import BytesIO |
@@ -242,3 +244,32 @@ def ls(self, path, detail=True, **kwargs): |
242 | 244 | return paths |
243 | 245 |
|
244 | 246 | return [self.info(_path) for _path in paths] |
| 247 | + |
| 248 | + def get_file( |
| 249 | + self, rpath, lpath, callback=_DEFAULT_CALLBACK, outfile=None, **kwargs |
| 250 | + ): |
| 251 | + # NOTE: temporary workaround while waiting for |
| 252 | + # https://github.com/fsspec/filesystem_spec/pull/1191 |
| 253 | + |
| 254 | + if isfilelike(lpath): |
| 255 | + outfile = lpath |
| 256 | + elif self.isdir(rpath): |
| 257 | + os.makedirs(lpath, exist_ok=True) |
| 258 | + return None |
| 259 | + |
| 260 | + with self.open(rpath, "rb", **kwargs) as f1: |
| 261 | + if outfile is None: |
| 262 | + outfile = open(lpath, "wb") |
| 263 | + |
| 264 | + try: |
| 265 | + callback.set_size(getattr(f1, "size", None)) |
| 266 | + data = True |
| 267 | + while data: |
| 268 | + data = f1.read(self.blocksize) |
| 269 | + segment_len = outfile.write(data) |
| 270 | + if segment_len is None: |
| 271 | + segment_len = len(data) |
| 272 | + callback.relative_update(segment_len) |
| 273 | + finally: |
| 274 | + if not isfilelike(lpath): |
| 275 | + outfile.close() |
0 commit comments