mirror of
https://github.com/bootandy/dust.git
synced 2026-06-08 11:29:05 +03:00
feat(win): use size on disk for apparent size for OneDrive files (#370)
* feat(win): use size on disk for apparent size for OneDrive files * apply changes from code review * run cargo fmt
This commit is contained in:
Generated
+10
@@ -249,6 +249,7 @@ dependencies = [
|
|||||||
"clap_mangen",
|
"clap_mangen",
|
||||||
"config-file",
|
"config-file",
|
||||||
"directories",
|
"directories",
|
||||||
|
"filesize",
|
||||||
"lscolors",
|
"lscolors",
|
||||||
"rayon",
|
"rayon",
|
||||||
"regex",
|
"regex",
|
||||||
@@ -284,6 +285,15 @@ version = "2.0.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5"
|
checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "filesize"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "12d741e2415d4e2e5bd1c1d00409d1a8865a57892c2d689b504365655d237d43"
|
||||||
|
dependencies = [
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "getrandom"
|
name = "getrandom"
|
||||||
version = "0.2.12"
|
version = "0.2.12"
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ sysinfo = "0.27"
|
|||||||
|
|
||||||
[target.'cfg(windows)'.dependencies]
|
[target.'cfg(windows)'.dependencies]
|
||||||
winapi-util = "0.1"
|
winapi-util = "0.1"
|
||||||
|
filesize = "0.2.0"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
assert_cmd = "2"
|
assert_cmd = "2"
|
||||||
|
|||||||
+35
-11
@@ -26,7 +26,7 @@ pub fn get_metadata(d: &Path, use_apparent_size: bool) -> Option<(u64, Option<(u
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_family = "windows")]
|
#[cfg(target_family = "windows")]
|
||||||
pub fn get_metadata(d: &Path, _use_apparent_size: bool) -> Option<(u64, Option<(u64, u64)>)> {
|
pub fn get_metadata(d: &Path, use_apparent_size: bool) -> Option<(u64, Option<(u64, u64)>)> {
|
||||||
// On windows opening the file to get size, file ID and volume can be very
|
// On windows opening the file to get size, file ID and volume can be very
|
||||||
// expensive because 1) it causes a few system calls, and more importantly 2) it can cause
|
// expensive because 1) it causes a few system calls, and more importantly 2) it can cause
|
||||||
// windows defender to scan the file.
|
// windows defender to scan the file.
|
||||||
@@ -90,16 +90,27 @@ pub fn get_metadata(d: &Path, _use_apparent_size: bool) -> Option<(u64, Option<(
|
|||||||
Ok(Handle::from_file(file))
|
Ok(Handle::from_file(file))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_metadata_expensive(d: &Path) -> Option<(u64, Option<(u64, u64)>)> {
|
fn get_metadata_expensive(
|
||||||
|
d: &Path,
|
||||||
|
use_apparent_size: bool,
|
||||||
|
) -> Option<(u64, Option<(u64, u64)>)> {
|
||||||
use winapi_util::file::information;
|
use winapi_util::file::information;
|
||||||
|
|
||||||
let h = handle_from_path_limited(d).ok()?;
|
let h = handle_from_path_limited(d).ok()?;
|
||||||
let info = information(&h).ok()?;
|
let info = information(&h).ok()?;
|
||||||
|
|
||||||
Some((
|
if use_apparent_size {
|
||||||
info.file_size(),
|
use filesize::PathExt;
|
||||||
Some((info.file_index(), info.volume_serial_number())),
|
Some((
|
||||||
))
|
d.size_on_disk().ok()?,
|
||||||
|
Some((info.file_index(), info.volume_serial_number())),
|
||||||
|
))
|
||||||
|
} else {
|
||||||
|
Some((
|
||||||
|
info.file_size(),
|
||||||
|
Some((info.file_index(), info.volume_serial_number())),
|
||||||
|
))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
use std::os::windows::fs::MetadataExt;
|
use std::os::windows::fs::MetadataExt;
|
||||||
@@ -111,18 +122,31 @@ pub fn get_metadata(d: &Path, _use_apparent_size: bool) -> Option<(u64, Option<(
|
|||||||
const FILE_ATTRIBUTE_SYSTEM: u32 = 0x04;
|
const FILE_ATTRIBUTE_SYSTEM: u32 = 0x04;
|
||||||
const FILE_ATTRIBUTE_NORMAL: u32 = 0x80;
|
const FILE_ATTRIBUTE_NORMAL: u32 = 0x80;
|
||||||
const FILE_ATTRIBUTE_DIRECTORY: u32 = 0x10;
|
const FILE_ATTRIBUTE_DIRECTORY: u32 = 0x10;
|
||||||
|
const FILE_ATTRIBUTE_SPARSE_FILE: u32 = 0x00000200;
|
||||||
|
const FILE_ATTRIBUTE_PINNED: u32 = 0x00080000;
|
||||||
|
const FILE_ATTRIBUTE_UNPINNED: u32 = 0x00100000;
|
||||||
|
const FILE_ATTRIBUTE_RECALL_ON_OPEN: u32 = 0x00040000;
|
||||||
|
const FILE_ATTRIBUTE_RECALL_ON_DATA_ACCESS: u32 = 0x00400000;
|
||||||
|
const FILE_ATTRIBUTE_OFFLINE: u32 = 0x00001000;
|
||||||
|
// normally FILE_ATTRIBUTE_SPARSE_FILE would be enough, however Windows sometimes likes to mask it out. see: https://stackoverflow.com/q/54560454
|
||||||
|
const IS_PROBABLY_ONEDRIVE: u32 = FILE_ATTRIBUTE_SPARSE_FILE
|
||||||
|
| FILE_ATTRIBUTE_PINNED
|
||||||
|
| FILE_ATTRIBUTE_UNPINNED
|
||||||
|
| FILE_ATTRIBUTE_RECALL_ON_OPEN
|
||||||
|
| FILE_ATTRIBUTE_RECALL_ON_DATA_ACCESS
|
||||||
|
| FILE_ATTRIBUTE_OFFLINE;
|
||||||
let attr_filtered = md.file_attributes()
|
let attr_filtered = md.file_attributes()
|
||||||
& !(FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_SYSTEM);
|
& !(FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_SYSTEM);
|
||||||
if (attr_filtered & FILE_ATTRIBUTE_ARCHIVE) != 0
|
if ((attr_filtered & FILE_ATTRIBUTE_ARCHIVE) != 0
|
||||||
|| (attr_filtered & FILE_ATTRIBUTE_DIRECTORY) != 0
|
|| (attr_filtered & FILE_ATTRIBUTE_DIRECTORY) != 0
|
||||||
|| md.file_attributes() == FILE_ATTRIBUTE_NORMAL
|
|| md.file_attributes() == FILE_ATTRIBUTE_NORMAL)
|
||||||
|
&& !((attr_filtered & IS_PROBABLY_ONEDRIVE != 0) && use_apparent_size)
|
||||||
{
|
{
|
||||||
Some((md.len(), None))
|
Some((md.len(), None))
|
||||||
} else {
|
} else {
|
||||||
get_metadata_expensive(d)
|
get_metadata_expensive(d, use_apparent_size)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => get_metadata_expensive(d),
|
_ => get_metadata_expensive(d, use_apparent_size),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user