mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-08-16 11:42:04 +08:00
feat(files): read & write using js buffers (#10093)
This commit is contained in:
@ -254,6 +254,44 @@ export class FileSystemAccess implements IFileSystemAccess {
|
|||||||
return this.getLogicalRootPath() + '/app';
|
return this.getLogicalRootPath() + '/app';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public readBuffer = this.readBufferSync.bind(this);
|
||||||
|
|
||||||
|
public readBufferAsync(path: string): Promise<ArrayBuffer> {
|
||||||
|
return new Promise<ArrayBuffer>((resolve, reject) => {
|
||||||
|
try {
|
||||||
|
org.nativescript.widgets.Async.File.readBuffer(
|
||||||
|
path,
|
||||||
|
new org.nativescript.widgets.Async.CompleteCallback({
|
||||||
|
onComplete: (result: java.nio.ByteBuffer) => {
|
||||||
|
resolve((ArrayBuffer as any).from(result));
|
||||||
|
},
|
||||||
|
onError: (err) => {
|
||||||
|
reject(new Error(err));
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
null
|
||||||
|
);
|
||||||
|
} catch (ex) {
|
||||||
|
reject(ex);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public readBufferSync(path: string, onError?: (error: any) => any) {
|
||||||
|
try {
|
||||||
|
const javaFile = new java.io.File(path);
|
||||||
|
const stream = new java.io.FileInputStream(javaFile);
|
||||||
|
const channel = stream.getChannel();
|
||||||
|
const buffer = new ArrayBuffer(javaFile.length());
|
||||||
|
channel.read(buffer as any);
|
||||||
|
return buffer;
|
||||||
|
} catch (exception) {
|
||||||
|
if (onError) {
|
||||||
|
onError(exception);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public read = this.readSync.bind(this);
|
public read = this.readSync.bind(this);
|
||||||
|
|
||||||
public readAsync(path: string): Promise<number[]> {
|
public readAsync(path: string): Promise<number[]> {
|
||||||
@ -293,6 +331,52 @@ export class FileSystemAccess implements IFileSystemAccess {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static getBuffer(buffer: ArrayBuffer | Uint8Array | Uint8ClampedArray): any {
|
||||||
|
if (buffer instanceof ArrayBuffer) {
|
||||||
|
return (buffer as any).nativeObject || buffer;
|
||||||
|
} else {
|
||||||
|
return (buffer?.buffer as any)?.nativeObject || buffer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public writeBuffer = this.writeBufferSync.bind(this);
|
||||||
|
|
||||||
|
public writeBufferAsync(path: string, buffer: ArrayBuffer | Uint8Array | Uint8ClampedArray): Promise<void> {
|
||||||
|
return new Promise<void>((resolve, reject) => {
|
||||||
|
try {
|
||||||
|
org.nativescript.widgets.Async.File.writeBuffer(
|
||||||
|
path,
|
||||||
|
FileSystemAccess.getBuffer(buffer),
|
||||||
|
new org.nativescript.widgets.Async.CompleteCallback({
|
||||||
|
onComplete: () => {
|
||||||
|
resolve();
|
||||||
|
},
|
||||||
|
onError: (err) => {
|
||||||
|
reject(new Error(err));
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
null
|
||||||
|
);
|
||||||
|
} catch (ex) {
|
||||||
|
reject(ex);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public writeBufferSync(path: string, buffer: ArrayBuffer | Uint8Array | Uint8ClampedArray, onError?: (error: any) => any) {
|
||||||
|
try {
|
||||||
|
const javaFile = new java.io.File(path);
|
||||||
|
const stream = new java.io.FileOutputStream(javaFile);
|
||||||
|
const channel = stream.getChannel();
|
||||||
|
channel.write(FileSystemAccess.getBuffer(buffer));
|
||||||
|
stream.close();
|
||||||
|
} catch (exception) {
|
||||||
|
if (onError) {
|
||||||
|
onError(exception);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public write = this.writeSync.bind(this);
|
public write = this.writeSync.bind(this);
|
||||||
|
|
||||||
public writeAsync(path: string, bytes: androidNative.Array<number>): Promise<void> {
|
public writeAsync(path: string, bytes: androidNative.Array<number>): Promise<void> {
|
||||||
@ -757,6 +841,7 @@ export class FileSystemAccess29 extends FileSystemAccess {
|
|||||||
getCurrentAppPath(): string {
|
getCurrentAppPath(): string {
|
||||||
return super.getCurrentAppPath();
|
return super.getCurrentAppPath();
|
||||||
}
|
}
|
||||||
|
|
||||||
public readText = this.readTextSync.bind(this);
|
public readText = this.readTextSync.bind(this);
|
||||||
|
|
||||||
readTextAsync(path: string, encoding?: any): Promise<string> {
|
readTextAsync(path: string, encoding?: any): Promise<string> {
|
||||||
@ -795,6 +880,47 @@ export class FileSystemAccess29 extends FileSystemAccess {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
readBuffer = this.readBufferSync.bind(this);
|
||||||
|
|
||||||
|
readBufferAsync(path: string): Promise<any> {
|
||||||
|
if (isContentUri(path)) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
getOrSetHelper(path).readBuffer(
|
||||||
|
applicationContext,
|
||||||
|
new org.nativescript.widgets.FileHelper.Callback({
|
||||||
|
onSuccess(result) {
|
||||||
|
resolve(result);
|
||||||
|
},
|
||||||
|
onError(error) {
|
||||||
|
reject(error);
|
||||||
|
},
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return super.readBufferAsync(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
readBufferSync(path: string, onError?: (error: any) => any) {
|
||||||
|
if (isContentUri(path)) {
|
||||||
|
let callback = null;
|
||||||
|
if (typeof onError === 'function') {
|
||||||
|
callback = new org.nativescript.widgets.FileHelper.Callback({
|
||||||
|
onSuccess(result) {},
|
||||||
|
onError(error) {
|
||||||
|
onError(error);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
const ret = getOrSetHelper(path).readBufferSync(applicationContext, callback);
|
||||||
|
if (ret) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return (ArrayBuffer as any).from(ret);
|
||||||
|
}
|
||||||
|
return super.readBufferSync(path, onError);
|
||||||
|
}
|
||||||
|
|
||||||
read = this.readSync.bind(this);
|
read = this.readSync.bind(this);
|
||||||
|
|
||||||
readAsync(path: string): Promise<any> {
|
readAsync(path: string): Promise<any> {
|
||||||
@ -872,6 +998,45 @@ export class FileSystemAccess29 extends FileSystemAccess {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
writeBuffer = this.writeBufferSync.bind(this);
|
||||||
|
|
||||||
|
writeBufferAsync(path: string, content: any): Promise<void> {
|
||||||
|
if (isContentUri(path)) {
|
||||||
|
return new Promise<void>((resolve, reject) => {
|
||||||
|
getOrSetHelper(path).writeBuffer(
|
||||||
|
applicationContext,
|
||||||
|
FileSystemAccess.getBuffer(content),
|
||||||
|
new org.nativescript.widgets.FileHelper.Callback({
|
||||||
|
onSuccess(result) {
|
||||||
|
resolve();
|
||||||
|
},
|
||||||
|
onError(error) {
|
||||||
|
reject(error);
|
||||||
|
},
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return super.writeAsync(path, content);
|
||||||
|
}
|
||||||
|
|
||||||
|
writeBufferSync(path: string, content: any, onError?: (error: any) => any) {
|
||||||
|
if (isContentUri(path)) {
|
||||||
|
let callback = null;
|
||||||
|
if (typeof onError === 'function') {
|
||||||
|
callback = new org.nativescript.widgets.FileHelper.Callback({
|
||||||
|
onSuccess(result) {},
|
||||||
|
onError(error) {
|
||||||
|
onError(error);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
getOrSetHelper(path).writeSync(applicationContext, FileSystemAccess.getBuffer(content), callback);
|
||||||
|
} else {
|
||||||
|
super.writeSync(path, content, onError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
write = this.writeSync.bind(this);
|
write = this.writeSync.bind(this);
|
||||||
|
|
||||||
writeAsync(path: string, content: any): Promise<void> {
|
writeAsync(path: string, content: any): Promise<void> {
|
||||||
|
@ -298,6 +298,12 @@ export class FileSystemAccess implements IFileSystemAccess {
|
|||||||
|
|
||||||
readTextSync(path: string, onError?: (error: any) => any, encoding?: any): string;
|
readTextSync(path: string, onError?: (error: any) => any, encoding?: any): string;
|
||||||
|
|
||||||
|
readBuffer(path: string, onError?: (error: any) => any): ArrayBuffer;
|
||||||
|
|
||||||
|
readBufferAsync(path: string): Promise<ArrayBuffer>;
|
||||||
|
|
||||||
|
readBufferSync(path: string, onError?: (error: any) => any): ArrayBuffer;
|
||||||
|
|
||||||
read(path: string, onError?: (error: any) => any): any;
|
read(path: string, onError?: (error: any) => any): any;
|
||||||
|
|
||||||
readAsync(path: string): Promise<any>;
|
readAsync(path: string): Promise<any>;
|
||||||
@ -310,6 +316,12 @@ export class FileSystemAccess implements IFileSystemAccess {
|
|||||||
|
|
||||||
writeTextSync(path: string, content: string, onError?: (error: any) => any, encoding?: any);
|
writeTextSync(path: string, content: string, onError?: (error: any) => any, encoding?: any);
|
||||||
|
|
||||||
|
writeBuffer(path: string, content: ArrayBuffer | Uint8Array | Uint8ClampedArray, onError?: (error: any) => any);
|
||||||
|
|
||||||
|
writeBufferAsync(path: string, content: ArrayBuffer | Uint8Array | Uint8ClampedArray): Promise<void>;
|
||||||
|
|
||||||
|
writeBufferSync(path: string, content: ArrayBuffer | Uint8Array | Uint8ClampedArray, onError?: (error: any) => any);
|
||||||
|
|
||||||
write(path: string, content: any, onError?: (error: any) => any);
|
write(path: string, content: any, onError?: (error: any) => any);
|
||||||
|
|
||||||
writeAsync(path: string, content: any): Promise<void>;
|
writeAsync(path: string, content: any): Promise<void>;
|
||||||
|
@ -294,6 +294,30 @@ export class FileSystemAccess {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public readBuffer = this.readBufferSync.bind(this);
|
||||||
|
|
||||||
|
public readBufferAsync(path: string): Promise<ArrayBuffer> {
|
||||||
|
return new Promise<ArrayBuffer>((resolve, reject) => {
|
||||||
|
try {
|
||||||
|
(NSData as any).dataWithContentsOfFileCompletion(path, (data) => {
|
||||||
|
resolve(interop.bufferFromData(data));
|
||||||
|
});
|
||||||
|
} catch (ex) {
|
||||||
|
reject(new Error("Failed to read file at path '" + path + "': " + ex));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public readBufferSync(path: string, onError?: (error: any) => any): ArrayBuffer {
|
||||||
|
try {
|
||||||
|
return interop.bufferFromData(NSData.dataWithContentsOfFile(path));
|
||||||
|
} catch (ex) {
|
||||||
|
if (onError) {
|
||||||
|
onError(new Error("Failed to read file at path '" + path + "': " + ex));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public read = this.readSync.bind(this);
|
public read = this.readSync.bind(this);
|
||||||
|
|
||||||
public readAsync(path: string): Promise<NSData> {
|
public readAsync(path: string): Promise<NSData> {
|
||||||
@ -352,6 +376,40 @@ export class FileSystemAccess {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static getBuffer(buffer: ArrayBuffer | Uint8Array | Uint8ClampedArray): NSData {
|
||||||
|
if (buffer instanceof ArrayBuffer) {
|
||||||
|
return NSData.dataWithData(buffer as any);
|
||||||
|
} else {
|
||||||
|
const buf = NSData.dataWithData(buffer?.buffer as any);
|
||||||
|
const len = buffer.byteLength;
|
||||||
|
return NSData.dataWithBytesNoCopyLength((buf.bytes as interop.Pointer).add(buffer?.byteOffset ?? 0), len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public writeBuffer = this.writeBufferSync.bind(this);
|
||||||
|
|
||||||
|
public writeBufferAsync(path: string, content: ArrayBuffer | Uint8Array | Uint8ClampedArray): Promise<void> {
|
||||||
|
return new Promise<void>((resolve, reject) => {
|
||||||
|
try {
|
||||||
|
FileSystemAccess.getBuffer(content).writeToFileAtomicallyCompletion(path, true, () => {
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
|
} catch (ex) {
|
||||||
|
reject(new Error("Failed to write file at path '" + path + "': " + ex));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public writeBufferSync(path: string, content: ArrayBuffer | Uint8Array | Uint8ClampedArray, onError?: (error: any) => any) {
|
||||||
|
try {
|
||||||
|
FileSystemAccess.getBuffer(content).writeToFileAtomically(path, true);
|
||||||
|
} catch (ex) {
|
||||||
|
if (onError) {
|
||||||
|
onError(new Error("Failed to write to file '" + path + "': " + ex));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public write = this.writeSync.bind(this);
|
public write = this.writeSync.bind(this);
|
||||||
|
|
||||||
public writeAsync(path: string, content: NSData): Promise<void> {
|
public writeAsync(path: string, content: NSData): Promise<void> {
|
||||||
|
Binary file not shown.
@ -31,8 +31,10 @@
|
|||||||
export module File {
|
export module File {
|
||||||
export function readText(path: string, encoding: string, callback: CompleteCallback, context: any);
|
export function readText(path: string, encoding: string, callback: CompleteCallback, context: any);
|
||||||
export function read(path: string, callback: CompleteCallback, context: any);
|
export function read(path: string, callback: CompleteCallback, context: any);
|
||||||
|
export function readBuffer(param0: string, param1: org.nativescript.widgets.Async.CompleteCallback, param2: any): void;
|
||||||
export function writeText(path: string, content: string, encoding: string, callback: CompleteCallback, context: any);
|
export function writeText(path: string, content: string, encoding: string, callback: CompleteCallback, context: any);
|
||||||
export function write(path: string, content: androidNative.Array<number>, callback: CompleteCallback, context: any);
|
export function write(path: string, content: androidNative.Array<number>, callback: CompleteCallback, context: any);
|
||||||
|
export function writeBuffer(param0: string, param1: java.nio.ByteBuffer, param2: org.nativescript.widgets.Async.CompleteCallback, param3: any): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export module Http {
|
export module Http {
|
||||||
@ -641,27 +643,31 @@ declare module org {
|
|||||||
export class FileHelper {
|
export class FileHelper {
|
||||||
public static class: java.lang.Class<org.nativescript.widgets.FileHelper>;
|
public static class: java.lang.Class<org.nativescript.widgets.FileHelper>;
|
||||||
public readText(param0: globalAndroid.content.Context, param1: string, param2: org.nativescript.widgets.FileHelper.Callback): void;
|
public readText(param0: globalAndroid.content.Context, param1: string, param2: org.nativescript.widgets.FileHelper.Callback): void;
|
||||||
public writeSync(param0: globalAndroid.content.Context, param1: androidNative.Array<number>, param2: org.nativescript.widgets.FileHelper.Callback): void;
|
public writeBufferSync(param0: globalAndroid.content.Context, param1: java.nio.ByteBuffer, param2: org.nativescript.widgets.FileHelper.Callback): void;
|
||||||
public static fromString(param1: globalAndroid.content.Context, param0: string): org.nativescript.widgets.FileHelper;
|
|
||||||
public writeText(param0: globalAndroid.content.Context, param1: string, param2: string, param3: org.nativescript.widgets.FileHelper.Callback): void;
|
|
||||||
public writeTextSync(param0: globalAndroid.content.Context, param1: string, param2: string, param3: org.nativescript.widgets.FileHelper.Callback): void;
|
public writeTextSync(param0: globalAndroid.content.Context, param1: string, param2: string, param3: org.nativescript.widgets.FileHelper.Callback): void;
|
||||||
public copyToFileSync(param0: globalAndroid.content.Context, param1: java.io.File, param2: org.nativescript.widgets.FileHelper.Callback): boolean;
|
public copyToFileSync(param0: globalAndroid.content.Context, param1: java.io.File, param2: org.nativescript.widgets.FileHelper.Callback): boolean;
|
||||||
public getName(): string;
|
|
||||||
public read(param0: globalAndroid.content.Context, param1: org.nativescript.widgets.FileHelper.Callback): void;
|
public read(param0: globalAndroid.content.Context, param1: org.nativescript.widgets.FileHelper.Callback): void;
|
||||||
public copyToFile(param0: globalAndroid.content.Context, param1: java.io.File, param2: org.nativescript.widgets.FileHelper.Callback): void;
|
public renameSync(param0: globalAndroid.content.Context, param1: string, param2: org.nativescript.widgets.FileHelper.Callback): void;
|
||||||
public static fromUri(param0: globalAndroid.content.Context, param1: globalAndroid.net.Uri): org.nativescript.widgets.FileHelper;
|
|
||||||
public readSync(param0: globalAndroid.content.Context, param1: org.nativescript.widgets.FileHelper.Callback): androidNative.Array<number>;
|
public readSync(param0: globalAndroid.content.Context, param1: org.nativescript.widgets.FileHelper.Callback): androidNative.Array<number>;
|
||||||
public write(param0: globalAndroid.content.Context, param1: androidNative.Array<number>, param2: org.nativescript.widgets.FileHelper.Callback): void;
|
public static fromString(param0: globalAndroid.content.Context, param1: string): org.nativescript.widgets.FileHelper;
|
||||||
public getSize(): number;
|
public getSize(): number;
|
||||||
public getMime(): string;
|
public getMime(): string;
|
||||||
public readTextSync(param0: globalAndroid.content.Context, param1: string, param2: org.nativescript.widgets.FileHelper.Callback): string;
|
public static exists(param0: globalAndroid.content.Context, param1: globalAndroid.net.Uri): boolean;
|
||||||
public delete(param0: globalAndroid.content.Context): boolean;
|
public delete(param0: globalAndroid.content.Context): boolean;
|
||||||
public static exists(param0: globalAndroid.content.Context, param1: string): boolean;
|
public writeSync(param0: globalAndroid.content.Context, param1: androidNative.Array<number>, param2: org.nativescript.widgets.FileHelper.Callback): void;
|
||||||
public static exists(param0: globalAndroid.content.Context, param1: globalAndroid.net.Uri): boolean;
|
public writeText(param0: globalAndroid.content.Context, param1: string, param2: string, param3: org.nativescript.widgets.FileHelper.Callback): void;
|
||||||
public getExtension(): string;
|
public readBuffer(param0: globalAndroid.content.Context, param1: org.nativescript.widgets.FileHelper.Callback): void;
|
||||||
public getLastModified(): number;
|
public getName(): string;
|
||||||
public renameSync(param0: globalAndroid.content.Context, param1: string, param2: org.nativescript.widgets.FileHelper.Callback): string;
|
public rename(param0: globalAndroid.content.Context, param1: string, param2: org.nativescript.widgets.FileHelper.Callback): void;
|
||||||
public rename(param0: globalAndroid.content.Context, param1: string, param2: org.nativescript.widgets.FileHelper.Callback): string;
|
public writeBuffer(param0: globalAndroid.content.Context, param1: java.nio.ByteBuffer, param2: org.nativescript.widgets.FileHelper.Callback): void;
|
||||||
|
public copyToFile(param0: globalAndroid.content.Context, param1: java.io.File, param2: org.nativescript.widgets.FileHelper.Callback): void;
|
||||||
|
public readBufferSync(param0: globalAndroid.content.Context, param1: org.nativescript.widgets.FileHelper.Callback): java.nio.ByteBuffer;
|
||||||
|
public write(param0: globalAndroid.content.Context, param1: androidNative.Array<number>, param2: org.nativescript.widgets.FileHelper.Callback): void;
|
||||||
|
public getExtension(): string;
|
||||||
|
public readTextSync(param0: globalAndroid.content.Context, param1: string, param2: org.nativescript.widgets.FileHelper.Callback): string;
|
||||||
|
public static fromUri(param0: globalAndroid.content.Context, param1: globalAndroid.net.Uri): org.nativescript.widgets.FileHelper;
|
||||||
|
public static exists(param0: globalAndroid.content.Context, param1: string): boolean;
|
||||||
|
public getLastModified(): number;
|
||||||
}
|
}
|
||||||
export module FileHelper {
|
export module FileHelper {
|
||||||
export class Callback {
|
export class Callback {
|
||||||
|
@ -26,7 +26,9 @@ import java.net.CookieHandler;
|
|||||||
import java.net.CookieManager;
|
import java.net.CookieManager;
|
||||||
import java.net.HttpURLConnection;
|
import java.net.HttpURLConnection;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.CharBuffer;
|
import java.nio.CharBuffer;
|
||||||
|
import java.nio.channels.FileChannel;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
@ -627,6 +629,23 @@ public class Async {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void readBuffer(final String path, final CompleteCallback callback, final Object context) {
|
||||||
|
final android.os.Handler mHandler = new android.os.Handler(Looper.myLooper());
|
||||||
|
threadPoolExecutor().execute(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
final ReadBufferTask task = new ReadBufferTask(callback, context);
|
||||||
|
final ByteBuffer result = task.doInBackground(path);
|
||||||
|
mHandler.post(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
task.onPostExecute(result);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public static void writeText(final String path, final String content, final String encoding, final CompleteCallback callback, final Object context) {
|
public static void writeText(final String path, final String content, final String encoding, final CompleteCallback callback, final Object context) {
|
||||||
final android.os.Handler mHandler = new android.os.Handler(Looper.myLooper());
|
final android.os.Handler mHandler = new android.os.Handler(Looper.myLooper());
|
||||||
threadPoolExecutor().execute(new Runnable() {
|
threadPoolExecutor().execute(new Runnable() {
|
||||||
@ -661,6 +680,23 @@ public class Async {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void writeBuffer(final String path, final ByteBuffer content, final CompleteCallback callback, final Object context) {
|
||||||
|
final android.os.Handler mHandler = new android.os.Handler(Looper.myLooper());
|
||||||
|
threadPoolExecutor().execute(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
final WriteBufferTask task = new WriteBufferTask(callback, context);
|
||||||
|
final boolean result = task.doInBackground(path, content);
|
||||||
|
mHandler.post(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
task.onPostExecute(result);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
static class ReadTextTask {
|
static class ReadTextTask {
|
||||||
private final CompleteCallback callback;
|
private final CompleteCallback callback;
|
||||||
private final Object context;
|
private final Object context;
|
||||||
@ -768,6 +804,55 @@ public class Async {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static class ReadBufferTask {
|
||||||
|
private final CompleteCallback callback;
|
||||||
|
private final Object context;
|
||||||
|
|
||||||
|
public ReadBufferTask(CompleteCallback callback, Object context) {
|
||||||
|
this.callback = callback;
|
||||||
|
this.context = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected ByteBuffer doInBackground(String... params) {
|
||||||
|
java.io.File javaFile = new java.io.File(params[0]);
|
||||||
|
FileInputStream stream = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
stream = new FileInputStream(javaFile);
|
||||||
|
|
||||||
|
ByteBuffer buffer = ByteBuffer.allocateDirect((int) javaFile.length());
|
||||||
|
|
||||||
|
FileChannel channel = stream.getChannel();
|
||||||
|
channel.read(buffer);
|
||||||
|
buffer.rewind();
|
||||||
|
|
||||||
|
return buffer;
|
||||||
|
} catch (FileNotFoundException e) {
|
||||||
|
Log.e(TAG, "Failed to read file, FileNotFoundException: " + e.getMessage());
|
||||||
|
return null;
|
||||||
|
} catch (IOException e) {
|
||||||
|
Log.e(TAG, "Failed to read file, IOException: " + e.getMessage());
|
||||||
|
return null;
|
||||||
|
} finally {
|
||||||
|
if (stream != null) {
|
||||||
|
try {
|
||||||
|
stream.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
Log.e(TAG, "Failed to close stream, IOException: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void onPostExecute(final ByteBuffer result) {
|
||||||
|
if (result != null) {
|
||||||
|
this.callback.onComplete(result, this.context);
|
||||||
|
} else {
|
||||||
|
this.callback.onError("ReadTask returns no result.", this.context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static class WriteTextTask {
|
static class WriteTextTask {
|
||||||
private final CompleteCallback callback;
|
private final CompleteCallback callback;
|
||||||
private final Object context;
|
private final Object context;
|
||||||
@ -784,7 +869,6 @@ public class Async {
|
|||||||
stream = new FileOutputStream(javaFile);
|
stream = new FileOutputStream(javaFile);
|
||||||
|
|
||||||
OutputStreamWriter writer = new OutputStreamWriter(stream, params[2]);
|
OutputStreamWriter writer = new OutputStreamWriter(stream, params[2]);
|
||||||
|
|
||||||
writer.write(params[1]);
|
writer.write(params[1]);
|
||||||
writer.close();
|
writer.close();
|
||||||
|
|
||||||
@ -863,5 +947,52 @@ public class Async {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static class WriteBufferTask {
|
||||||
|
private final CompleteCallback callback;
|
||||||
|
private final Object context;
|
||||||
|
|
||||||
|
public WriteBufferTask(CompleteCallback callback, Object context) {
|
||||||
|
this.callback = callback;
|
||||||
|
this.context = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean doInBackground(Object... params) {
|
||||||
|
java.io.File javaFile = new java.io.File((String) params[0]);
|
||||||
|
FileOutputStream stream = null;
|
||||||
|
ByteBuffer content = (ByteBuffer) params[1];
|
||||||
|
|
||||||
|
try {
|
||||||
|
stream = new FileOutputStream(javaFile);
|
||||||
|
FileChannel channel = stream.getChannel();
|
||||||
|
content.rewind();
|
||||||
|
channel.write(content);
|
||||||
|
content.rewind();
|
||||||
|
return true;
|
||||||
|
} catch (FileNotFoundException e) {
|
||||||
|
Log.e(TAG, "Failed to write file, FileNotFoundException: " + e.getMessage());
|
||||||
|
return false;
|
||||||
|
} catch (IOException e) {
|
||||||
|
Log.e(TAG, "Failed to write file, IOException: " + e.getMessage());
|
||||||
|
return false;
|
||||||
|
} finally {
|
||||||
|
if (stream != null) {
|
||||||
|
try {
|
||||||
|
stream.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
Log.e(TAG, "Failed to close stream, IOException: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void onPostExecute(final boolean result) {
|
||||||
|
if (result) {
|
||||||
|
this.callback.onComplete(null, this.context);
|
||||||
|
} else {
|
||||||
|
this.callback.onError("WriteTask returns no result.", this.context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,11 @@ import java.io.InputStream;
|
|||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.io.OutputStreamWriter;
|
import java.io.OutputStreamWriter;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.channels.Channels;
|
||||||
|
import java.nio.channels.FileChannel;
|
||||||
|
import java.nio.channels.ReadableByteChannel;
|
||||||
|
import java.nio.channels.WritableByteChannel;
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
|
|
||||||
@ -302,8 +307,7 @@ public class FileHelper {
|
|||||||
}
|
}
|
||||||
return context.getContentResolver().openInputStream(uri);
|
return context.getContentResolver().openInputStream(uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private OutputStream getOutputStream(Context context, Uri uri) throws Exception {
|
private OutputStream getOutputStream(Context context, Uri uri) throws Exception {
|
||||||
if (Build.VERSION.SDK_INT >= 19) {
|
if (Build.VERSION.SDK_INT >= 19) {
|
||||||
if (isExternalStorageDocument(uri)) {
|
if (isExternalStorageDocument(uri)) {
|
||||||
@ -332,6 +336,16 @@ public class FileHelper {
|
|||||||
return ret.buf();
|
return ret.buf();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ByteBuffer readBufferSyncInternal(Context context) throws Exception {
|
||||||
|
InputStream is = getInputStream(context, uri);
|
||||||
|
|
||||||
|
ReadableByteChannel channel = Channels.newChannel(is);
|
||||||
|
ByteBuffer buffer = ByteBuffer.allocateDirect(is.available());
|
||||||
|
channel.read(buffer);
|
||||||
|
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
public @Nullable
|
public @Nullable
|
||||||
byte[] readSync(Context context, @Nullable Callback callback) {
|
byte[] readSync(Context context, @Nullable Callback callback) {
|
||||||
try {
|
try {
|
||||||
@ -355,6 +369,29 @@ public class FileHelper {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public @Nullable
|
||||||
|
ByteBuffer readBufferSync(Context context, @Nullable Callback callback) {
|
||||||
|
try {
|
||||||
|
return readBufferSyncInternal(context);
|
||||||
|
} catch (Exception e) {
|
||||||
|
if (callback != null) {
|
||||||
|
callback.onError(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void readBuffer(Context context, Callback callback) {
|
||||||
|
executor.execute(() -> {
|
||||||
|
try {
|
||||||
|
ByteBuffer result = readBufferSyncInternal(context);
|
||||||
|
handler.post(() -> callback.onSuccess(result));
|
||||||
|
} catch (Exception e) {
|
||||||
|
handler.post(() -> callback.onError(e));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private String readTextSyncInternal(Context context, @Nullable String encoding) throws Exception {
|
private String readTextSyncInternal(Context context, @Nullable String encoding) throws Exception {
|
||||||
String characterSet = encoding;
|
String characterSet = encoding;
|
||||||
if (characterSet == null) {
|
if (characterSet == null) {
|
||||||
@ -400,6 +437,15 @@ public class FileHelper {
|
|||||||
updateInternal(context);
|
updateInternal(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void writeBufferSyncInternal(Context context,ByteBuffer content) throws Exception {
|
||||||
|
OutputStream os = getOutputStream(context, uri);
|
||||||
|
WritableByteChannel channel = Channels.newChannel(os);
|
||||||
|
channel.write(content);
|
||||||
|
os.flush();
|
||||||
|
os.close();
|
||||||
|
updateInternal(context);
|
||||||
|
}
|
||||||
|
|
||||||
public void writeSync(Context context, byte[] content, @Nullable Callback callback) {
|
public void writeSync(Context context, byte[] content, @Nullable Callback callback) {
|
||||||
try {
|
try {
|
||||||
writeSyncInternal(context, content);
|
writeSyncInternal(context, content);
|
||||||
@ -421,6 +467,27 @@ public class FileHelper {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void writeBufferSync(Context context, ByteBuffer content, @Nullable Callback callback) {
|
||||||
|
try {
|
||||||
|
writeBufferSyncInternal(context, content);
|
||||||
|
} catch (Exception e) {
|
||||||
|
if (callback != null) {
|
||||||
|
callback.onError(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeBuffer(Context context, ByteBuffer content, Callback callback) {
|
||||||
|
executor.execute(() -> {
|
||||||
|
try {
|
||||||
|
writeBufferSyncInternal(context, content);
|
||||||
|
handler.post(() -> callback.onSuccess(null));
|
||||||
|
} catch (Exception e) {
|
||||||
|
handler.post(() -> callback.onError(e));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private void writeTextSyncInternal(Context context, String content, @Nullable String encoding) throws Exception {
|
private void writeTextSyncInternal(Context context, String content, @Nullable String encoding) throws Exception {
|
||||||
OutputStream os = getOutputStream(context, uri);
|
OutputStream os = getOutputStream(context, uri);
|
||||||
String characterSet = encoding;
|
String characterSet = encoding;
|
||||||
|
Reference in New Issue
Block a user