close method

  1. @override
Future<void> close()
override

Close the target consumer.

NOTE: Writes to the IOSink may be buffered, and may not be flushed by a call to close(). To flush all buffered writes, call flush() before calling close().

Implementation

@override
Future<void> close() async {
  if (_doneCompleter.isCompleted) {
    return _doneCompleter.future;
  }

  client.log('WebDAV: close() called on file sink for $remotePath');

  try {
    final remoteParentPath = p.dirname(remotePath);

    // Resolve parent folder
    final parentResolved = await client.resolvePath(remoteParentPath);
    if (parentResolved['type'] != 'folder') {
      throw io.FileSystemException('Invalid parent path', remoteParentPath);
    }

    // Overwrite semantics: Filen permits duplicate names, so an
    // unconditional upload over an existing path would create a sibling
    // rather than replace it. Trash any existing file at this path first
    // (mirrors filen-python's end_write) so a PUT replaces it.
    try {
      final existing = await client.resolvePath(remotePath);
      if (existing['type'] == 'file') {
        await client.trashItem(existing['uuid'], 'file');
      }
    } catch (_) {
      // No existing entry at this path -> nothing to replace.
    }

    final io.File localFileToUpload; // Non-nullable declaration

    if (_usingDisk) {
      await _tempFileSink!.close();
      localFileToUpload = _tempFile!;
      client
          .log('WebDAV: Uploading large file from disk: ${_tempFile!.path}');
    } else {
      final bytes = _memoryBuffer.takeBytes();
      client.log(
          'WebDAV: Uploading small file from memory (${bytes.length} bytes)');
      final tempFile = io.File(p.join(
        io.Directory.systemTemp.path,
        'filen-webdav-upload-small-${DateTime.now().millisecondsSinceEpoch}',
      ));
      await tempFile.writeAsBytes(bytes);
      localFileToUpload = tempFile;
    }

    // Get timestamps if preserving
    String? creationTime;
    String? modificationTime;
    if (preserveTimestamps) {
      try {
        final stat = await localFileToUpload.stat();
        modificationTime = stat.modified.millisecondsSinceEpoch.toString();
        creationTime = stat.changed.millisecondsSinceEpoch.toString();
      } catch (_) {}
    }

    // Upload the file
    await client.uploadFile(
      localFileToUpload,
      parentResolved['uuid'],
      creationTime: creationTime,
      modificationTime: modificationTime,
    );

    _doneCompleter.complete();
  } catch (e, s) {
    client.log('WebDAV: Error during sink close: $e\n$s');
    _doneCompleter.completeError(e, s);
    throw io.FileSystemException('Error writing file', remotePath);
  } finally {
    if (_tempFile != null && await _tempFile!.exists()) {
      await _tempFile!.delete();
    }
  }

  return _doneCompleter.future;
}