Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiple file modified events fired per file save #27

Open
richardeakin opened this issue Feb 3, 2021 · 3 comments
Open

Multiple file modified events fired per file save #27

richardeakin opened this issue Feb 3, 2021 · 3 comments

Comments

@richardeakin
Copy link

Hi,

I'm testing out this nice library in an UE4 setting and noticing that while it is working quite well for add and remove, modified is firing twice whenever I update a file (save it in a text editor). Is this a known thing, or is there some way I can avoid it?

Also, when I add a new file to my watched directory, I see two events: one add and one modified - perhaps this is a hint to the problem. Here is the code I'm testing with in a C++ Actor. Note I'm also printing the current frame, which is sometimes the same for the redundant modified event, sometimes it is a frame later.

// Fill out your copyright notice in the Description page of Project Settings.


#include "FileMonitorTest.h"
#include "./FileWatch.hpp"
#include <string>

#define PRINT_DISPLAY_TIME 3.0f
#define printf(format, ...)                 if (GEngine) GEngine->AddOnScreenDebugMessage(-1, PRINT_DISPLAY_TIME, FColor::White, FString::Printf(TEXT(format), ##__VA_ARGS__), false)

// Sets default values
AFileMonitorTest::AFileMonitorTest()
{
 	// Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
	PrimaryActorTick.bCanEverTick = true;

}

namespace {
const char* watchEventTypeToString( const filewatch::Event change_type )
{
	switch (change_type) {
		case filewatch::Event::added:			return "added";
		case filewatch::Event::removed:			return "removed";
		case filewatch::Event::modified:		return "modified";
		case filewatch::Event::renamed_old:		return "renamed_old";
		case filewatch::Event::renamed_new:		return "renamed_new";
		default: break;
	};

	return "(unknown)";
}
}

// Called when the game starts or when spawned
void AFileMonitorTest::BeginPlay()
{
	Super::BeginPlay();
	
	// we'll add a watcher for file changes in this directory
	std::wstring scanDir( L"E:/epic/Unreal Projects/FileMonitoring/data/scans" );

	IPlatformFile& PlatformFile = FPlatformFileManager::Get().GetPlatformFile();
	bool dirExists = PlatformFile.DirectoryExists(scanDir.c_str());
	printf("scanDir: %s, exists: %d", scanDir.c_str(), dirExists );

	if( dirExists ) {
		// print out contents of folder using ue4 stuffs
		TArray<FString> fileNames;
		PlatformFile.FindFiles( fileNames, scanDir.c_str(), NULL );
		printf("num files: %d", fileNames.Num() );
		for( int i = 0; i < fileNames.Num(); i++ ) {
			printf( "%s", *fileNames[i] );
		}

		// watch for file changes within scanDir
		static filewatch::FileWatch<std::wstring> watch(
			scanDir, 
			[](const std::wstring& path, const filewatch::Event change_type ) {
				FString changeTypeStr = watchEventTypeToString( change_type );using char* directly prints rubbish
				printf("path: %s, event type: %s, frame: %d", path.c_str(), *changeTypeStr, GFrameNumber );
			}
		);
	}
}

// Called every frame
void AFileMonitorTest::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);

}
@richardeakin
Copy link
Author

Another interesting note: if I hit save one an empty file, then I only get one modified event fired. But if it has contents, then I get two modified events fired.

@deadash
Copy link

deadash commented Nov 11, 2021

I also have this problem in windows, if I delete and write it is removed\added\modified.
If it is modified directly, it is modified twice.

@deadash
Copy link

deadash commented Nov 11, 2021

There seems to be no good way to solve this problem

Most people use the anti-shake function call, or view the last modification time of the file.

You can use procmon to check the occurrence of the event, it should also be twice.

https://stackoverflow.com/questions/1764809/filesystemwatcher-changed-event-is-raised-twice
https://stackoverflow.com/questions/14036449/c-winapi-readdirectorychangesw-receiving-double-notifications

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants