feat(file): copy sync and async support (#10273)

This commit is contained in:
Osei Fortune
2023-04-21 23:36:01 -04:00
committed by GitHub
parent 1b17e23bb6
commit c63a50a196
9 changed files with 308 additions and 1 deletions

View File

@ -254,6 +254,42 @@ export class FileSystemAccess implements IFileSystemAccess {
return this.getLogicalRootPath() + '/app';
}
public copy = this.copySync.bind(this);
public copySync(src: string, dest: string, onError?: (error: any) => any) {
try {
return org.nativescript.widgets.Async.File.copySync(src, dest, getApplicationContext());
} catch (error) {
if (onError) {
onError(exception);
}
}
return false;
}
public copyAsync(src: string, dest: string): Promise<boolean> {
return new Promise<boolean>((resolve, reject) => {
try {
org.nativescript.widgets.Async.File.copy(
src,
dest,
new org.nativescript.widgets.Async.CompleteCallback({
onComplete: (result: boolean) => {
resolve(result);
},
onError: (err) => {
reject(new Error(err));
},
}),
getApplicationContext()
);
} catch (ex) {
reject(ex);
}
});
}
public readBuffer = this.readBufferSync.bind(this);
public readBufferAsync(path: string): Promise<ArrayBuffer> {

View File

@ -2,6 +2,32 @@
* An utility class used to provide methods to access and work with the file system.
*/
export interface IFileSystemAccess {
/**
* Copies a file to a given path.
* @param src The path to the source file.
* @param dest The path to the destination file.
* @param onError (optional) A callback function to use if any error occurs.
* Returns a Promise with a boolean.
*/
copy(src: string, dest: string, onError?: (error: any) => any): any;
/**
* Copies a file to a given path.
* @param src The path to the source file.
* @param dest The path to the destination file.
* Returns a Promise with a boolean.
*/
copyAsync(src: string, dest: string): Promise<any>;
/**
* Copies a file to a given path.
* @param src The path to the source file.
* @param dest The path to the destination file.
* @param onError (optional) A callback function to use if any error occurs.
* Returns a Promise with a boolean.
*/
copySync(src: string, dest: string, onError?: (error: any) => any): any;
/**
* Gets the last modified date of a file with a given path.
* @param path Path to the file.
@ -256,6 +282,12 @@ export interface IFileSystemAccess {
}
export class FileSystemAccess implements IFileSystemAccess {
copy(src: string, dest: string, onError?: (error: any) => any): boolean;
copySync(src: string, dest: string, onError?: (error: any) => any): boolean;
copyAsync(src: string, dest: string): Promise<boolean>;
getLastModified(path: string): Date;
getFileSize(path: string): number;

View File

@ -260,6 +260,65 @@ export class FileSystemAccess {
return iOSNativeHelper.getCurrentAppPath();
}
public copy = this.copySync.bind(this);
public copySync(src: string, dest: string, onError?: (error: any) => any) {
const fileManager = NSFileManager.defaultManager;
try {
return fileManager.copyItemAtPathToPathError(src, dest);
} catch (error) {
if (error.message.indexOf('exists') > -1) {
// check the size of file if empty remove then try copying again
// this could be zero due to using File.fromPath passing in a new file
let didRemove = false;
try {
didRemove = fileManager.removeItemAtPathError(dest);
return fileManager.copyItemAtPathToPathError(src, dest);
} catch (error) {
if (onError) {
if (didRemove) {
onError(error);
} else {
onError(exception);
}
}
}
}
if (onError) {
onError(exception);
}
}
return false;
}
public copyAsync(src: string, dest: string): Promise<boolean> {
return new Promise<boolean>((resolve, reject) => {
try {
NSData.dataWithContentsOfFileCompletion(src, (data) => {
if (!data) {
reject(new Error("Failed to read file at path '" + src));
} else {
data.writeToFileAtomicallyCompletion(dest, true, () => {
if (this.fileExists(dest)) {
const size = this.getFileSize(dest);
if (size === data.length) {
resolve(true);
} else {
reject(new Error("Failed to write file at path '" + dest));
}
} else {
reject(new Error("Failed to write file at path '" + dest));
}
});
}
});
} catch (ex) {
reject(ex);
}
});
}
public readText = this.readTextSync.bind(this);
public readTextAsync(path: string, encoding?: any) {

View File

@ -211,6 +211,53 @@ export class File extends FileSystemEntity {
return getFileAccess().getFileSize(this.path);
}
public copy(dest: string): Promise<boolean> {
return new Promise<boolean>((resolve, reject) => {
try {
this._checkAccess();
} catch (ex) {
reject(ex);
return;
}
this._locked = true;
getFileAccess()
.copyAsync(this.path, dest)
.then(
(result) => {
resolve(result);
this._locked = false;
},
(error) => {
reject(error);
this._locked = false;
}
);
});
}
public copySync(dest: string, onError?: (error: any) => any): any {
this._checkAccess();
this._locked = true;
const that = this;
const localError = (error) => {
that._locked = false;
if (onError) {
onError(error);
}
};
const content = getFileAccess().copySync(this.path, dest, localError);
this._locked = false;
return content;
}
public read(): Promise<any> {
return new Promise<any>((resolve, reject) => {
try {