Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
how to get a file's modified date/time and size in bytes?
#11
Quote:Sure, let's create a function in C that retrieves the last modified date and time of a file in a cross-platform manner. We'll use the standard library functions available in C for both Unix-like systems (Linux, macOS) and Windows.

### Plan

1. **Include necessary headers**: We need to include different headers depending on the platform.
2. **Define the function**: The function `get_last_modified_time` will take a file path as an argument.
3. **Platform-specific code**:
  - For Unix-like systems, we'll use `stat` to get the file's metadata.
  - For Windows, we'll use `GetFileAttributesEx` to get the file's metadata.
4. **Format the output**: We'll format the output to display the last modified date and time.

Here’s the complete C code:

```c
#include <stdio.h>
#include <time.h>
#ifdef _WIN32
#include <windows.h>
#else
#include <sys/stat.h>
#endif

void get_last_modified_time(const char *filepath) {
#ifdef _WIN32
    WIN32_FILE_ATTRIBUTE_DATA fileInfo;
    if (GetFileAttributesEx(filepath, GetFileExInfoStandard, &fileInfo)) {
        FILETIME ft = fileInfo.ftLastWriteTime;
        SYSTEMTIME st;
        FileTimeToSystemTime(&ft, &st);
        printf("Last modified date and time: %02d/%02d/%d %02d:%02d:%02d\n",
              st.wDay, st.wMonth, st.wYear,
              st.wHour, st.wMinute, st.wSecond);
    } else {
        printf("Failed to get file attributes for %s\n", filepath);
    }
#else
    struct stat attr;
    if (stat(filepath, &attr) == 0) {
        struct tm *tm_info = localtime(&attr.st_mtime);
        char buffer[30];
        strftime(buffer, 30, "%Y-%m-%d %H:%M:%S", tm_info);
        printf("Last modified date and time: %s\n", buffer);
    } else {
        perror("stat");
    }
#endif
}

int main() {
    const char *filepath = "path/to/your/file.txt";
    get_last_modified_time(filepath);
    return 0;
}
```

### Explanation

1. **Headers**:
  - `stdio.h` for input/output functions.
  - `time.h` for time manipulation.
  - `windows.h` for Windows-specific file attributes.
  - `sys/stat.h` for Unix-like system file attributes.

2. **Function**:
  - `get_last_modified_time` is defined to handle both Unix-like and Windows systems.
  - On Windows, `GetFileAttributesEx` is used to get file information and `FileTimeToSystemTime` to convert it to a readable format.
  - On Unix-like systems, `stat` is used to get file information and `localtime` to convert the last modification time to a readable format.

3. **Main Function**:
  - Example usage with a placeholder file path.
  - Call to `get_last_modified_time` to print the last modified date and time.

### Suggestions for Next Steps

**a.** Add error handling for different edge cases (e.g., file not found, permission issues).

**b.** Modify the function to return the last modified date and time as a string instead of printing it.
Tread on those who tread on you

Reply
#12
(05-22-2024, 06:42 PM)SpriggsySpriggs Wrote:
Quote:Sure, let's create a function in C that retrieves the last modified date and time of a file in a cross-platform manner. We'll use the standard library functions available in C for both Unix-like systems (Linux, macOS) and Windows.

### Plan

1. **Include necessary headers**: We need to include different headers depending on the platform.
2. **Define the function**: The function `get_last_modified_time` will take a file path as an argument.
3. **Platform-specific code**:
  - For Unix-like systems, we'll use `stat` to get the file's metadata.
  - For Windows, we'll use `GetFileAttributesEx` to get the file's metadata.
4. **Format the output**: We'll format the output to display the last modified date and time.

Here’s the complete C code:

```c
#include <stdio.h>
#include <time.h>
#ifdef _WIN32
#include <windows.h>
#else
#include <sys/stat.h>
#endif

void get_last_modified_time(const char *filepath) {
#ifdef _WIN32
    WIN32_FILE_ATTRIBUTE_DATA fileInfo;
    if (GetFileAttributesEx(filepath, GetFileExInfoStandard, &fileInfo)) {
        FILETIME ft = fileInfo.ftLastWriteTime;
        SYSTEMTIME st;
        FileTimeToSystemTime(&ft, &st);
        printf("Last modified date and time: %02d/%02d/%d %02d:%02d:%02d\n",
              st.wDay, st.wMonth, st.wYear,
              st.wHour, st.wMinute, st.wSecond);
    } else {
        printf("Failed to get file attributes for %s\n", filepath);
    }
#else
    struct stat attr;
    if (stat(filepath, &attr) == 0) {
        struct tm *tm_info = localtime(&attr.st_mtime);
        char buffer[30];
        strftime(buffer, 30, "%Y-%m-%d %H:%M:%S", tm_info);
        printf("Last modified date and time: %s\n", buffer);
    } else {
        perror("stat");
    }
#endif
}

int main() {
    const char *filepath = "path/to/your/file.txt";
    get_last_modified_time(filepath);
    return 0;
}
```

### Explanation

1. **Headers**:
  - `stdio.h` for input/output functions.
  - `time.h` for time manipulation.
  - `windows.h` for Windows-specific file attributes.
  - `sys/stat.h` for Unix-like system file attributes.

2. **Function**:
  - `get_last_modified_time` is defined to handle both Unix-like and Windows systems.
  - On Windows, `GetFileAttributesEx` is used to get file information and `FileTimeToSystemTime` to convert it to a readable format.
  - On Unix-like systems, `stat` is used to get file information and `localtime` to convert the last modification time to a readable format.

3. **Main Function**:
  - Example usage with a placeholder file path.
  - Call to `get_last_modified_time` to print the last modified date and time.

### Suggestions for Next Steps

**a.** Add error handling for different edge cases (e.g., file not found, permission issues).

**b.** Modify the function to return the last modified date and time as a string instead of printing it.
Wow, that was fast! 
Did someone already suggest this? 
Did you have GPT write that? Is that sarcasm? LoL
I don't expect the team to implement every suggestion, but figure if there is something that might be useful to others, may as well contribute it to the list...
Reply
#13
I had GPT4 write it. I just asked it to create a cross platform C function to grab last modified date/time.

I would have used GPT4o but I saw that someone had made a code-specific GPT on the GPT Store so I went with that instead.
Tread on those who tread on you

Reply
#14
(05-22-2024, 06:42 PM)SpriggsySpriggs Wrote:
Quote:Sure, let's create a function in C that retrieves the last modified date and time of a file in a cross-platform manner. We'll use the standard library functions available in C for both Unix-like systems (Linux, macOS) and Windows.

### Plan

1. **Include necessary headers**: We need to include different headers depending on the platform.
2. **Define the function**: The function `get_last_modified_time` will take a file path as an argument.
3. **Platform-specific code**:
  - For Unix-like systems, we'll use `stat` to get the file's metadata.
  - For Windows, we'll use `GetFileAttributesEx` to get the file's metadata.
4. **Format the output**: We'll format the output to display the last modified date and time.

Here’s the complete C code:

```c
#include <stdio.h>
#include <time.h>
#ifdef _WIN32
#include <windows.h>
#else
#include <sys/stat.h>
#endif

void get_last_modified_time(const char *filepath) {
#ifdef _WIN32
    WIN32_FILE_ATTRIBUTE_DATA fileInfo;
    if (GetFileAttributesEx(filepath, GetFileExInfoStandard, &fileInfo)) {
        FILETIME ft = fileInfo.ftLastWriteTime;
        SYSTEMTIME st;
        FileTimeToSystemTime(&ft, &st);
        printf("Last modified date and time: %02d/%02d/%d %02d:%02d:%02d\n",
              st.wDay, st.wMonth, st.wYear,
              st.wHour, st.wMinute, st.wSecond);
    } else {
        printf("Failed to get file attributes for %s\n", filepath);
    }
#else
    struct stat attr;
    if (stat(filepath, &attr) == 0) {
        struct tm *tm_info = localtime(&attr.st_mtime);
        char buffer[30];
        strftime(buffer, 30, "%Y-%m-%d %H:%M:%S", tm_info);
        printf("Last modified date and time: %s\n", buffer);
    } else {
        perror("stat");
    }
#endif
}

int main() {
    const char *filepath = "path/to/your/file.txt";
    get_last_modified_time(filepath);
    return 0;
}
```

### Explanation

1. **Headers**:
  - `stdio.h` for input/output functions.
  - `time.h` for time manipulation.
  - `windows.h` for Windows-specific file attributes.
  - `sys/stat.h` for Unix-like system file attributes.

2. **Function**:
  - `get_last_modified_time` is defined to handle both Unix-like and Windows systems.
  - On Windows, `GetFileAttributesEx` is used to get file information and `FileTimeToSystemTime` to convert it to a readable format.
  - On Unix-like systems, `stat` is used to get file information and `localtime` to convert the last modification time to a readable format.

3. **Main Function**:
  - Example usage with a placeholder file path.
  - Call to `get_last_modified_time` to print the last modified date and time.

### Suggestions for Next Steps

**a.** Add error handling for different edge cases (e.g., file not found, permission issues).

**b.** Modify the function to return the last modified date and time as a string instead of printing it.

No big deal, but since QB64PE uses gcc/g++ for Windows, you don't need the "#ifdef WIN32" part, since stat() also works on Windows.
For instance, this:
Code: (Select All)
#include <stdio.h>
#include <time.h>
#include <sys/stat.h>

void get_last_modified_time(const char *filepath) {
    struct stat attr;
    if (stat(filepath, &attr) == 0) {
        struct tm *tm_info = localtime(&attr.st_mtime);
        char buffer[30];
        strftime(buffer, 30, "%Y-%m-%d %H:%M:%S", tm_info);
        printf("Last modified date and time: %s\n", buffer);
    } else {
        perror("stat");
    }
}

int main(int argc, char *argv[]) {
    const char *filepath = argv[1];
    if (argc < 2) {
        printf("Usage: foo filename\n");
    } else {
        get_last_modified_time(filepath);
    }
    return 0;
}
Compiles and runs under Windows.

Again, no big deal, just a friendly FYI.
Reply
#15
(05-22-2024, 07:21 PM)SpriggsySpriggs Wrote: I had GPT4 write it. I just asked it to create a cross platform C function to grab last modified date/time.

I would have used GPT4o but I saw that someone had made a code-specific GPT on the GPT Store so I went with that instead.
Wow that's great! 
Do you think GPT will help the QB64PE devs in general?
Reply
#16
(05-22-2024, 06:20 PM)madscijr Wrote:
(05-22-2024, 05:04 PM)SpriggsySpriggs Wrote: I guess I'm going to have to become the old geezer who complains that everyone is ruining hard drives with temp files constantly.
Ha! 

Well in this case I was looking to see if a file changed on disk, and only access it if it changed. 
I figured looking at the timestamp and size in bytes are a good way to tell. 
The problem with using this SHELL method that creates a file is, it requires at least 3 disk accesses: 
  1. one to read the attributes
  2. one to write them to a temp file, and 
  3. one to read that file 
  4. (and another if we want to delete the temp file)

Not too efficient. For a lot of cases that might not be a big deal, but for what I'm doing, it would slow things down a lot.

We have a thread somewhere to suggest new commands for QB64PE, right? Where can I suggest adding some built-in cross-platform commands to get a file's date / size / attributes (& maybe update them as well)?
Note that you can use wmic to get all sorts of attribute information on your files, easily from the command line:

Code: (Select All)
AccessMask=1507775
Archive=FALSE
Caption=Z:\foo.pdf
Compressed=TRUE
CompressionMethod=Compressed
CreationClassName=CIM_LogicalFile
CreationDate=20240518233126.540393-240
CSCreationClassName=Win32_ComputerSystem
CSName=LAPTOP
Description=Z:\foo.pdf
Drive=z:
EightDotThreeFileName=z:\foo.pdf
Encrypted=FALSE
EncryptionMethod=
Extension=pdf
FileName=foo
FileSize=34339
FileType=pdf File
FSCreationClassName=Win32_FileSystem
FSName=NTFS
Hidden=FALSE
InstallDate=20240518233126.540393-240
InUseCount=
LastAccessed=20240522175359.607566-240
LastModified=20240501171800.893675-240
Manufacturer=
Name=Z:\foo.pdf
Path=\
Readable=TRUE
Status=OK
System=FALSE
Version=
Writeable=TRUE
All from this simple program: 
Code: (Select All)
$Console:Only
Shell "wmic DataFile where " + Chr$(34) + "Name='Z:\\foo.pdf'" + Chr$(34) + " list /format:list"
Reply
#17
Information 
(05-22-2024, 10:03 PM)SMcNeill Wrote: Note that you can use wmic to get all sorts of attribute information on your files, easily from the command line:

That's good to know, and gives me a "bright idea", LoL.
Actually this might be useful for a bunch of things, not just this...
What about a command (or option / flag) that runs a command prompt, but instead of piping the output to a file, it goes straight into memory, and populates a string variable?
That would simplify things a little.

Either way, that wmic can come in handy.
What about the Mac/Linux equivanent?

And what can be used to update a file's attributes?
Say you want to alter a file's Modified Date, or make it read only or writable?

Thanks for sharing the wmic info.
Reply
#18
madscijr, it sounds like you want to use pipecom
Tread on those who tread on you

Reply
#19
(05-23-2024, 03:33 PM)SpriggsySpriggs Wrote: madscijr, it sounds like you want to use pipecom
Ah yes... 

Check out the current iteration of the multi mouse in works in progress - would pipecom be appropriate for that? 

If you have a minute, send a link to the pipecom page again and any examples that demonstrate it, that would be grear
t. Thanks
Reply
#20
In Visual Basic (Excel, Word... MSOffice) you have, for this job:

MySize = FileLen("TESTFILE") 
MyStamp$ = FileDateTime("TESTFILE")    ' Returns ... "18/10/2019 11:55:27". 

Perhaps one day theese commands will exist in QB64 Big Grin
Why not yes ?
Reply




Users browsing this thread: 9 Guest(s)