mirror of
https://github.com/tauri-apps/tauri.git
synced 2026-01-31 00:35:19 +01:00
Support writing binary file to local disk (#580)
Co-authored-by: Lucas Fernandes Nogueira <lucasfernandesnog@gmail.com> Co-authored-by: Lucas Fernandes Nogueira <lucas@tauri.studio>
This commit is contained in:
@@ -70,6 +70,7 @@ If you are interested in making a tauri-app, please visit the [documentation web
|
||||
- [x] renameFile - rename a file
|
||||
- [x] copyFile - copy a file to a new destination
|
||||
- [x] writeFile - write file to local filesystem
|
||||
- [x] writeBinaryFile - write binary file to local filesystem
|
||||
- [x] readBinaryFile - read binary file from local filesystem
|
||||
- [x] readTextFile - read text file from local filesystem
|
||||
|
||||
|
||||
@@ -39,6 +39,56 @@ function writeFile (file, options = {}) {
|
||||
return tauri.writeFile(file, options)
|
||||
}
|
||||
|
||||
const CHUNK_SIZE = 65536;
|
||||
|
||||
/**
|
||||
* convert an Uint8Array to ascii string
|
||||
*
|
||||
* @param {Uint8Array} arr
|
||||
* @return {String}
|
||||
*/
|
||||
function uint8ArrayToString(arr) {
|
||||
if (arr.length < CHUNK_SIZE) {
|
||||
return String.fromCharCode.apply(null, arr)
|
||||
}
|
||||
|
||||
let result = ''
|
||||
const arrLen = arr.length
|
||||
for (let i = 0; i < arrLen; i++) {
|
||||
const chunk = arr.subarray(i * CHUNK_SIZE, (i + 1) * CHUNK_SIZE)
|
||||
result += String.fromCharCode.apply(null, chunk)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* convert an ArrayBuffer to base64 encoded string
|
||||
*
|
||||
* @param {ArrayBuffer} buffer
|
||||
* @return {String}
|
||||
*/
|
||||
function arrayBufferToBase64(buffer) {
|
||||
const str = uint8ArrayToString(new Uint8Array(buffer))
|
||||
return btoa(str)
|
||||
}
|
||||
|
||||
/**
|
||||
* writes a binary file
|
||||
*
|
||||
* @param {Object} file
|
||||
* @param {String} file.path path of the file
|
||||
* @param {ArrayBuffer} file.contents contents of the file
|
||||
* @param {Object} [options] configuration object
|
||||
* @param {BaseDirectory} [options.dir] base directory
|
||||
* @return {Promise<void>}
|
||||
*/
|
||||
function writeBinaryFile(file, options = {}) {
|
||||
return tauri.writeBinaryFile({
|
||||
...file,
|
||||
contents: arrayBufferToBase64(file.contents)
|
||||
}, options)
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {Object} FileEntry
|
||||
* @property {String} path
|
||||
@@ -131,6 +181,7 @@ export {
|
||||
readTextFile,
|
||||
readBinaryFile,
|
||||
writeFile,
|
||||
writeBinaryFile,
|
||||
readDir,
|
||||
createDir,
|
||||
removeDir,
|
||||
|
||||
@@ -205,6 +205,28 @@ window.tauri = {
|
||||
<% } %>
|
||||
},
|
||||
|
||||
<% if (ctx.dev) { %>
|
||||
/**
|
||||
* @name writeBinaryFile
|
||||
* @description Write a binary file to the Local Filesystem.
|
||||
* Permissions based on the app's PID owner
|
||||
* @param {Object} cfg
|
||||
* @param {String} cfg.file
|
||||
* @param {String|Binary} cfg.contents
|
||||
*/
|
||||
<% } %>
|
||||
writeBinaryFile (cfg) {
|
||||
<% if (tauri.whitelist.writeBinaryFile === true || tauri.whitelist.all === true) { %>
|
||||
Object.freeze(cfg)
|
||||
this.invoke({ cmd: 'writeBinaryFile', file: cfg.file, contents: cfg.contents })
|
||||
<% } else { %>
|
||||
<% if (ctx.dev) { %>
|
||||
__whitelistWarning('writeBinaryFile')
|
||||
<% } %>
|
||||
return __reject
|
||||
<% } %>
|
||||
},
|
||||
|
||||
<% if (ctx.dev) { %>
|
||||
/**
|
||||
* @name listFiles
|
||||
|
||||
@@ -43,7 +43,7 @@ switch (navigator.platform) {
|
||||
case "Win32":
|
||||
case "Win64":
|
||||
break;
|
||||
default:
|
||||
default:
|
||||
window.external = this
|
||||
invoke = function (x) {
|
||||
window.webkit.messageHandlers.external.postMessage(x);
|
||||
@@ -320,6 +320,37 @@ switch (navigator.platform) {
|
||||
<% } %>
|
||||
},
|
||||
|
||||
<% if (ctx.dev) { %>
|
||||
/**
|
||||
* @name writeBinaryFile
|
||||
* @description Write a binary file to the Local Filesystem.
|
||||
* Permissions based on the app's PID owner
|
||||
* @param {Object} cfg
|
||||
* @param {String} cfg.file
|
||||
* @param {String|Binary} cfg.contents
|
||||
* @param {Object} [options]
|
||||
* @param {BaseDirectory} [options.dir]
|
||||
*/
|
||||
<% } %>
|
||||
writeBinaryFile: function writeBinaryFile(cfg, options) {
|
||||
<% if (tauri.whitelist.writeBinaryFile === true || tauri.whitelist.all === true) { %>
|
||||
if (_typeof(cfg) === 'object') {
|
||||
Object.freeze(cfg);
|
||||
}
|
||||
return this.promisified({
|
||||
cmd: 'writeBinaryFile',
|
||||
file: cfg.file,
|
||||
contents: cfg.contents,
|
||||
options: options
|
||||
});
|
||||
<% } else { %>
|
||||
<% if (ctx.dev) { %>
|
||||
return __whitelistWarning('writeBinaryFile')
|
||||
<% } %>
|
||||
return __reject()
|
||||
<% } %>
|
||||
},
|
||||
|
||||
<% if (ctx.dev) { %>
|
||||
/**
|
||||
* @name readDir
|
||||
@@ -343,8 +374,7 @@ switch (navigator.platform) {
|
||||
<% if (ctx.dev) { %>
|
||||
return __whitelistWarning('readDir')
|
||||
<% } %>
|
||||
return __reject()
|
||||
<% } %>
|
||||
<% } %>
|
||||
},
|
||||
|
||||
<% if (ctx.dev) { %>
|
||||
|
||||
@@ -52,6 +52,16 @@ pub(crate) fn handle<T: 'static>(webview: &mut WebView<'_, T>, arg: &str) -> cra
|
||||
} => {
|
||||
file_system::write_file(webview, file, contents, options, callback, error);
|
||||
}
|
||||
#[cfg(any(feature = "all-api", feature = "write-binary-file"))]
|
||||
WriteBinaryFile {
|
||||
file,
|
||||
contents,
|
||||
options,
|
||||
callback,
|
||||
error,
|
||||
} => {
|
||||
file_system::write_binary_file(webview, file, contents, options, callback, error);
|
||||
}
|
||||
#[cfg(any(feature = "all-api", feature = "read-dir"))]
|
||||
ReadDir {
|
||||
path,
|
||||
|
||||
@@ -65,6 +65,14 @@ pub enum Cmd {
|
||||
callback: String,
|
||||
error: String,
|
||||
},
|
||||
#[cfg(any(feature = "all-api", feature = "write-binary-file"))]
|
||||
WriteBinaryFile {
|
||||
file: String,
|
||||
contents: String,
|
||||
options: Option<FileOperationOptions>,
|
||||
callback: String,
|
||||
error: String,
|
||||
},
|
||||
#[cfg(any(feature = "all-api", feature = "read-dir"))]
|
||||
ReadDir {
|
||||
path: String,
|
||||
|
||||
@@ -194,6 +194,34 @@ pub fn write_file<T: 'static>(
|
||||
);
|
||||
}
|
||||
|
||||
pub fn write_binary_file<T: 'static>(
|
||||
webview: &mut WebView<'_, T>,
|
||||
file: String,
|
||||
contents: String,
|
||||
options: Option<FileOperationOptions>,
|
||||
callback: String,
|
||||
error: String,
|
||||
) {
|
||||
crate::execute_promise(
|
||||
webview,
|
||||
move || {
|
||||
base64::decode(contents)
|
||||
.map_err(|e| e.into())
|
||||
.and_then(|c| {
|
||||
File::create(resolve_path(file, options.and_then(|o| o.dir))?)
|
||||
.map_err(|e| e.into())
|
||||
.and_then(|mut f| {
|
||||
f.write_all(&c)
|
||||
.map_err(|err| err.into())
|
||||
.map(|_| "".to_string())
|
||||
})
|
||||
})
|
||||
},
|
||||
callback,
|
||||
error,
|
||||
);
|
||||
}
|
||||
|
||||
pub fn read_text_file<T: 'static>(
|
||||
webview: &mut WebView<'_, T>,
|
||||
path: String,
|
||||
|
||||
Reference in New Issue
Block a user