如何在Mac OS X 10.15.1中读取磁盘IO?无需CoreFoundation/IOKit框架
Hey there! Since you're running macOS 10.15.1 and want to avoid relying on CoreFoundation or IOKit for disk IO stats, here are a few solid, framework-free approaches you can use:
1. Parse output from the built-in iostat command
macOS comes with iostat out of the box, which provides detailed disk IO metrics. You can invoke it from your program using standard C functions like popen() to capture and parse its output—no extra frameworks required.
Here's a quick example to get continuous stats for a specific disk (replace disk0 with your target disk):
#include <stdio.h> #include <string.h> int main() { FILE *fp = popen("iostat -d -w 1 disk0", "r"); if (!fp) return 1; char buffer[256]; // Skip the initial header lines while (fgets(buffer, sizeof(buffer), fp)) { if (strstr(buffer, "tps")) break; } // Read and process ongoing stats while (fgets(buffer, sizeof(buffer), fp)) { // The line includes columns like tps, rMB/s, wMB/s, %b (busy percentage) printf("Captured stat line: %s", buffer); // Add your custom parsing logic here to extract specific metrics } pclose(fp); return 0; }
The tradeoff here is handling string parsing, but it's straightforward for most use cases and leverages a tool that's well-tested on macOS.
2. Use the BSD getfsstat() system call
getfsstat() is a low-level BSD system call that retrieves filesystem statistics, including IO-related metrics like total read/write operations and block counts. It works with standard C headers only—no need for CoreFoundation or IOKit.
Check out this example:
#include <stdio.h> #include <stdlib.h> #include <sys/param.h> #include <sys/mount.h> int main() { struct statfs *buf; // First get the number of mounted filesystems int count = getfsstat(NULL, 0, MNT_NOWAIT); if (count <= 0) return 1; buf = malloc(count * sizeof(struct statfs)); if (!buf) return 1; // Fetch the actual stats count = getfsstat(buf, count * sizeof(struct statfs), MNT_NOWAIT); for (int i = 0; i < count; i++) { // Filter for local disk filesystems (skip tmpfs, network mounts, etc.) if (buf[i].f_type == MFS_LOCAL) { printf("Filesystem: %s\n", buf[i].f_mntfromname); printf("Total read operations: %llu\n", buf[i].f_reads); printf("Total write operations: %llu\n", buf[i].f_writes); // Check `man statfs` for more fields like read/write bytes on your macOS version } } free(buf); return 0; }
Note: The exact fields in struct statfs can vary slightly by macOS version—refer to the statfs(2) man page for details specific to 10.15.1.
3. Query disk stats via the sysctl interface
The sysctl() system call lets you fetch raw kernel-level statistics directly, similar to how Linux's /proc/diskstats works. On macOS, you can access disk stats using the kern.diskstats OID.
Here's a snippet to get you started:
#include <stdio.h> #include <sys/sysctl.h> int main() { int mib[] = {CTL_KERN, KERN_DISKSTATS}; char buffer[4096]; size_t len = sizeof(buffer); if (sysctl(mib, 2, buffer, &len, NULL, 0) == -1) { perror("sysctl failed"); return 1; } // The buffer contains newline-separated entries with disk name, reads, writes, bytes, etc. printf("Raw disk stats:\n%s", buffer); // Add parsing logic to extract the metrics you need return 0; }
This approach gives you direct access to kernel data without any framework overhead, making it the closest equivalent to Linux's /proc filesystem method.
All three options use standard C/BSD APIs or built-in system tools, so you won't need to link against CoreFoundation or IOKit. Pick the one that best fits your use case—sysctl for raw kernel stats, getfsstat for structured filesystem data, or iostat for easy-to-parse human-readable output.
内容的提问来源于stack exchange,提问作者Neel

