A handle is an abstract object.
I am assuming that you are using IDA for static analysis, and that you are not using any embedded debugger through IDA. Correct me if it's not the case.
From a static analysis point of view, you can't trace back the object where is comes from only with its value (100 in your exemple). The handle value is going to be different each time it is being used, so it is not relevant for a static analysis with IDA.
Since you are specifically asking for IDA, take a look at what is happening before your ReadFile() call.
As ReadFile() take a handle as an input, you should find a place in the code where this handle is being open. Something like a call to CreateFile (for instance). This is where you'll find the filename mapped with this handle value.
You can always try to search for cross-reference (shortcut 'X' in IDA) to the local variable that is holding your handle to retrieve the place where the handle is being open.
If the handle is not saved to a local variable, just trace back the register that is holding your handle.
Or simple search for imports that are coherent with what you are looking
Take a look at this small example:
HANDLE hFile = CreateFile( "C:\\filename.txt", // <- what you are looking for
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED,
NULL);
[...]
int result = ReadFile( hFile, // <- what you are looking at
ReadBuffer,
BUFFERSIZE-1,
&ol,
FileIOCompletionRoutine);
You need to go back a bit in the code's flow to search where this handle was opened first.
If you want to go the lazy way, you can either use a debugger, they all supports handle tracing. As you exclude x64dbg in your question, try with another one. If a tool is not working, pick another one and see.
If it's still not working (anti-debug/static analysis too painful), I would rather try to investigate the 'whatever reason' that prevent you from tracing CreateFiles() calls.