github.com/cyverse/go-irodsclient@v0.13.2/fs/fs_bulk.go (about) 1 package fs 2 3 import ( 4 "bytes" 5 "os" 6 "path/filepath" 7 8 "github.com/cyverse/go-irodsclient/irods/common" 9 irods_fs "github.com/cyverse/go-irodsclient/irods/fs" 10 "github.com/cyverse/go-irodsclient/irods/types" 11 "github.com/cyverse/go-irodsclient/irods/util" 12 "golang.org/x/xerrors" 13 ) 14 15 // DownloadFile downloads a file to local 16 func (fs *FileSystem) DownloadFile(irodsPath string, resource string, localPath string, callback common.TrackerCallBack) error { 17 irodsSrcPath := util.GetCorrectIRODSPath(irodsPath) 18 localDestPath := util.GetCorrectLocalPath(localPath) 19 20 localFilePath := localDestPath 21 22 srcStat, err := fs.Stat(irodsSrcPath) 23 if err != nil { 24 return xerrors.Errorf("failed to stat for path %s: %w", irodsSrcPath, types.NewFileNotFoundError(irodsSrcPath)) 25 } 26 27 if srcStat.Type == DirectoryEntry { 28 return xerrors.Errorf("cannot download a collection %s", irodsSrcPath) 29 } 30 31 destStat, err := os.Stat(localDestPath) 32 if err != nil { 33 if os.IsNotExist(err) { 34 // file not exists, it's a file 35 // pass 36 } else { 37 return err 38 } 39 } else { 40 if destStat.IsDir() { 41 irodsFileName := util.GetIRODSPathFileName(irodsSrcPath) 42 localFilePath = filepath.Join(localDestPath, irodsFileName) 43 } 44 } 45 46 return irods_fs.DownloadDataObject(fs.ioSession, irodsSrcPath, resource, localFilePath, srcStat.Size, callback) 47 } 48 49 // DownloadFileResumable downloads a file to local with support of transfer resume 50 func (fs *FileSystem) DownloadFileResumable(irodsPath string, resource string, localPath string, callback common.TrackerCallBack) error { 51 irodsSrcPath := util.GetCorrectIRODSPath(irodsPath) 52 localDestPath := util.GetCorrectLocalPath(localPath) 53 54 localFilePath := localDestPath 55 56 srcStat, err := fs.Stat(irodsSrcPath) 57 if err != nil { 58 return xerrors.Errorf("failed to stat for path %s: %w", irodsSrcPath, types.NewFileNotFoundError(irodsSrcPath)) 59 } 60 61 if srcStat.Type == DirectoryEntry { 62 return xerrors.Errorf("cannot download a collection %s", irodsSrcPath) 63 } 64 65 destStat, err := os.Stat(localDestPath) 66 if err != nil { 67 if os.IsNotExist(err) { 68 // file not exists, it's a file 69 // pass 70 } else { 71 return err 72 } 73 } else { 74 if destStat.IsDir() { 75 irodsFileName := util.GetIRODSPathFileName(irodsSrcPath) 76 localFilePath = filepath.Join(localDestPath, irodsFileName) 77 } 78 } 79 80 return irods_fs.DownloadDataObjectResumable(fs.ioSession, irodsSrcPath, resource, localFilePath, srcStat.Size, callback) 81 } 82 83 // DownloadFileToBuffer downloads a file to buffer 84 func (fs *FileSystem) DownloadFileToBuffer(irodsPath string, resource string, buffer bytes.Buffer, callback common.TrackerCallBack) error { 85 irodsSrcPath := util.GetCorrectIRODSPath(irodsPath) 86 87 srcStat, err := fs.Stat(irodsSrcPath) 88 if err != nil { 89 return xerrors.Errorf("failed to stat for path %s: %w", irodsSrcPath, types.NewFileNotFoundError(irodsSrcPath)) 90 } 91 92 if srcStat.Type == DirectoryEntry { 93 return xerrors.Errorf("cannot download a collection %s", irodsSrcPath) 94 } 95 96 return irods_fs.DownloadDataObjectToBuffer(fs.ioSession, irodsSrcPath, resource, buffer, srcStat.Size, callback) 97 } 98 99 // DownloadFileParallel downloads a file to local in parallel 100 func (fs *FileSystem) DownloadFileParallel(irodsPath string, resource string, localPath string, taskNum int, callback common.TrackerCallBack) error { 101 irodsSrcPath := util.GetCorrectIRODSPath(irodsPath) 102 localDestPath := util.GetCorrectLocalPath(localPath) 103 104 localFilePath := localDestPath 105 106 srcStat, err := fs.Stat(irodsSrcPath) 107 if err != nil { 108 return xerrors.Errorf("failed to stat for path %s: %w", irodsSrcPath, types.NewFileNotFoundError(irodsSrcPath)) 109 } 110 111 if srcStat.Type == DirectoryEntry { 112 return xerrors.Errorf("cannot download a collection %s", irodsSrcPath) 113 } 114 115 destStat, err := os.Stat(localDestPath) 116 if err != nil { 117 if os.IsNotExist(err) { 118 // file not exists, it's a file 119 // pass 120 } else { 121 return err 122 } 123 } else { 124 if destStat.IsDir() { 125 irodsFileName := util.GetIRODSPathFileName(irodsSrcPath) 126 localFilePath = filepath.Join(localDestPath, irodsFileName) 127 } 128 } 129 130 return irods_fs.DownloadDataObjectParallel(fs.ioSession, irodsSrcPath, resource, localFilePath, srcStat.Size, taskNum, callback) 131 } 132 133 // DownloadFileParallelResumable downloads a file to local in parallel with support of transfer resume 134 func (fs *FileSystem) DownloadFileParallelResumable(irodsPath string, resource string, localPath string, taskNum int, callback common.TrackerCallBack) error { 135 irodsSrcPath := util.GetCorrectIRODSPath(irodsPath) 136 localDestPath := util.GetCorrectLocalPath(localPath) 137 138 localFilePath := localDestPath 139 140 srcStat, err := fs.Stat(irodsSrcPath) 141 if err != nil { 142 return xerrors.Errorf("failed to stat for path %s: %w", irodsSrcPath, types.NewFileNotFoundError(irodsSrcPath)) 143 } 144 145 if srcStat.Type == DirectoryEntry { 146 return xerrors.Errorf("cannot download a collection %s", irodsSrcPath) 147 } 148 149 destStat, err := os.Stat(localDestPath) 150 if err != nil { 151 if os.IsNotExist(err) { 152 // file not exists, it's a file 153 // pass 154 } else { 155 return err 156 } 157 } else { 158 if destStat.IsDir() { 159 irodsFileName := util.GetIRODSPathFileName(irodsSrcPath) 160 localFilePath = filepath.Join(localDestPath, irodsFileName) 161 } 162 } 163 164 return irods_fs.DownloadDataObjectParallelResumable(fs.ioSession, irodsSrcPath, resource, localFilePath, srcStat.Size, taskNum, callback) 165 } 166 167 // UploadFile uploads a local file to irods 168 func (fs *FileSystem) UploadFile(localPath string, irodsPath string, resource string, replicate bool, callback common.TrackerCallBack) error { 169 localSrcPath := util.GetCorrectLocalPath(localPath) 170 irodsDestPath := util.GetCorrectIRODSPath(irodsPath) 171 172 irodsFilePath := irodsDestPath 173 174 stat, err := os.Stat(localSrcPath) 175 if err != nil { 176 if os.IsNotExist(err) { 177 // file not exists 178 return xerrors.Errorf("failed to stat for local path %s: %w", localSrcPath, types.NewFileNotFoundError(localSrcPath)) 179 } 180 return err 181 } 182 183 if stat.IsDir() { 184 return xerrors.Errorf("failed to find a file for local path %s, the path is for a directory: %w", localSrcPath, types.NewFileNotFoundError(localSrcPath)) 185 } 186 187 entry, err := fs.Stat(irodsDestPath) 188 if err != nil { 189 if !types.IsFileNotFoundError(err) { 190 return err 191 } 192 } else { 193 switch entry.Type { 194 case FileEntry: 195 // do nothing 196 case DirectoryEntry: 197 localFileName := filepath.Base(localSrcPath) 198 irodsFilePath = util.MakeIRODSPath(irodsDestPath, localFileName) 199 default: 200 return xerrors.Errorf("unknown entry type %s", entry.Type) 201 } 202 } 203 204 err = irods_fs.UploadDataObject(fs.ioSession, localSrcPath, irodsFilePath, resource, replicate, callback) 205 if err != nil { 206 return err 207 } 208 209 fs.invalidateCacheForFileCreate(irodsFilePath) 210 fs.cachePropagation.PropagateFileCreate(irodsFilePath) 211 return nil 212 } 213 214 // UploadFileFromBuffer uploads buffer data to irods 215 func (fs *FileSystem) UploadFileFromBuffer(buffer bytes.Buffer, irodsPath string, resource string, replicate bool, callback common.TrackerCallBack) error { 216 irodsDestPath := util.GetCorrectIRODSPath(irodsPath) 217 218 irodsFilePath := irodsDestPath 219 220 entry, err := fs.Stat(irodsDestPath) 221 if err != nil { 222 if !types.IsFileNotFoundError(err) { 223 return err 224 } 225 } else { 226 switch entry.Type { 227 case FileEntry: 228 // do nothing 229 case DirectoryEntry: 230 return xerrors.Errorf("invalid entry type %s. Destination must be a file", entry.Type) 231 default: 232 return xerrors.Errorf("unknown entry type %s", entry.Type) 233 } 234 } 235 236 err = irods_fs.UploadDataObjectFromBuffer(fs.ioSession, buffer, irodsFilePath, resource, replicate, callback) 237 if err != nil { 238 return err 239 } 240 241 fs.invalidateCacheForFileCreate(irodsFilePath) 242 fs.cachePropagation.PropagateFileCreate(irodsFilePath) 243 return nil 244 } 245 246 // UploadFileParallel uploads a local file to irods in parallel 247 func (fs *FileSystem) UploadFileParallel(localPath string, irodsPath string, resource string, taskNum int, replicate bool, callback common.TrackerCallBack) error { 248 localSrcPath := util.GetCorrectLocalPath(localPath) 249 irodsDestPath := util.GetCorrectIRODSPath(irodsPath) 250 251 irodsFilePath := irodsDestPath 252 253 srcStat, err := os.Stat(localSrcPath) 254 if err != nil { 255 if os.IsNotExist(err) { 256 // file not exists 257 return xerrors.Errorf("failed to stat for local path %s: %w", localSrcPath, types.NewFileNotFoundError(localSrcPath)) 258 } 259 return err 260 } 261 262 if srcStat.IsDir() { 263 return xerrors.Errorf("failed to find a file for local path %s, the path is for a directory: %w", localSrcPath, types.NewFileNotFoundError(localSrcPath)) 264 } 265 266 destStat, err := fs.Stat(irodsDestPath) 267 if err != nil { 268 if !types.IsFileNotFoundError(err) { 269 return err 270 } 271 } else { 272 switch destStat.Type { 273 case FileEntry: 274 // do nothing 275 case DirectoryEntry: 276 localFileName := filepath.Join(localSrcPath) 277 irodsFilePath = util.MakeIRODSPath(irodsDestPath, localFileName) 278 default: 279 return xerrors.Errorf("unknown entry type %s", destStat.Type) 280 } 281 } 282 283 err = irods_fs.UploadDataObjectParallel(fs.ioSession, localSrcPath, irodsFilePath, resource, taskNum, replicate, callback) 284 if err != nil { 285 return err 286 } 287 288 fs.invalidateCacheForFileCreate(irodsFilePath) 289 fs.cachePropagation.PropagateFileCreate(irodsFilePath) 290 return nil 291 }