@@ -1419,6 +1419,112 @@ operations related to the part of the file being truncated is undefined.
14191419
14201420
14211421
1422+ ### ` boolean copyFromLocalFile(boolean delSrc, boolean overwrite, Path src, Path dst) `
1423+
1424+ The source file or directory at ` src ` is on the local disk and is copied into the file system at
1425+ destination ` dst ` . If the source must be deleted after the move then ` delSrc ` flag must be
1426+ set to TRUE. If destination already exists, and the destination contents must be overwritten
1427+ then ` overwrite ` flag must be set to TRUE.
1428+
1429+ #### Preconditions
1430+ Source and destination must be different
1431+ ``` python
1432+ if src = dest : raise FileExistsException
1433+ ```
1434+
1435+ Destination and source must not be descendants one another
1436+ ``` python
1437+ if isDescendant(src, dest) or isDescendant(dest, src) : raise IOException
1438+ ```
1439+
1440+ The source file or directory must exist locally:
1441+ ``` python
1442+ if not exists(LocalFS, src) : raise FileNotFoundException
1443+ ```
1444+
1445+ Directories cannot be copied into files regardless to what the overwrite flag is set to:
1446+
1447+ ``` python
1448+ if isDir(LocalFS, src) and isFile(FS , dst) : raise PathExistsException
1449+ ```
1450+
1451+ For all cases, except the one for which the above precondition throws, the overwrite flag must be
1452+ set to TRUE for the operation to succeed if destination exists. This will also overwrite any files
1453+ / directories at the destination:
1454+
1455+ ``` python
1456+ if exists(FS , dst) and not overwrite : raise PathExistsException
1457+ ```
1458+
1459+ #### Determining the final name of the copy
1460+ Given a base path on the source ` base ` and a child path ` child ` where ` base ` is in
1461+ ` ancestors(child) + child ` :
1462+
1463+ ``` python
1464+ def final_name (base , child , dest ):
1465+ is base = child:
1466+ return dest
1467+ else :
1468+ return dest + childElements(base, child)
1469+ ```
1470+
1471+ #### Outcome where source is a file ` isFile(LocalFS, src) `
1472+ For a file, data at destination becomes that of the source. All ancestors are directories.
1473+ ``` python
1474+ if isFile(LocalFS, src) and (not exists(FS , dest) or (exists(FS , dest) and overwrite)):
1475+ FS ' = FS where:
1476+ FS ' .Files[dest] = LocalFS.Files[src]
1477+ FS ' .Directories = FS.Directories + ancestors(FS, dest)
1478+ LocalFS' = LocalFS where
1479+ not delSrc or (delSrc = true and delete(LocalFS, src, false))
1480+ else if isFile(LocalFS, src) and isDir(FS , dest):
1481+ FS ' = FS where:
1482+ let d = final_name(src, dest)
1483+ FS ' .Files[d] = LocalFS.Files[src]
1484+ LocalFS' = LocalFS where:
1485+ not delSrc or (delSrc = true and delete(LocalFS, src, false))
1486+ ```
1487+ There are no expectations that the file changes are atomic for both local ` LocalFS ` and remote ` FS ` .
1488+
1489+ #### Outcome where source is a directory ` isDir(LocalFS, src) `
1490+ ``` python
1491+ if isDir(LocalFS, src) and (isFile(FS , dest) or isFile(FS , dest + childElements(src))):
1492+ raise FileAlreadyExistsException
1493+ else if isDir(LocalFS, src):
1494+ if exists(FS , dest):
1495+ dest' = dest + childElements(src)
1496+ if exists(FS , dest' ) and not overwrite:
1497+ raise PathExistsException
1498+ else :
1499+ dest' = dest
1500+
1501+ FS ' = FS where:
1502+ forall c in descendants(LocalFS, src):
1503+ not exists(FS ' , final_name(c)) or overwrite
1504+ and forall c in descendants(LocalFS, src) where isDir(LocalFS, c):
1505+ FS ' .Directories = FS' .Directories + (dest' + childElements(src, c))
1506+ and forall c in descendants(LocalFS, src) where isFile(LocalFS, c):
1507+ FS ' .Files[final_name(c, dest' )] = LocalFS.Files[c]
1508+ LocalFS' = LocalFS where
1509+ not delSrc or (delSrc = true and delete(LocalFS, src, true))
1510+ ```
1511+ There are no expectations of operation isolation / atomicity.
1512+ This means files can change in source or destination while the operation is executing.
1513+ No guarantees are made for the final state of the file or directory after a copy other than it is
1514+ best effort. E.g.: when copying a directory, one file can be moved from source to destination but
1515+ there' s nothing stopping the new file at destination being updated while the copy operation is still
1516+ in place.
1517+
1518+ # ### Implementation
1519+
1520+ The default HDFS implementation, is to recurse through each file and folder, found at `src` , and
1521+ copy them sequentially to their final destination (relative to `dst` ).
1522+
1523+ Object store based file systems should be mindful of what limitations arise from the above
1524+ implementation and could take advantage of parallel uploads and possible re- ordering of files copied
1525+ into the store to maximize throughput.
1526+
1527+
14221528# # <a name="RemoteIterator"></a> interface `RemoteIterator`
14231529
14241530The `RemoteIterator` interface is used as a remote- access equivalent
0 commit comments