# Unable to Close FileChannel, opened with NIO

**URL:** <https://forum.inductiveautomation.com/t/unable-to-close-filechannel-opened-with-nio/53861>\
**Category:** Ignition\
**Tags:** ignition81, perspective\
**Created:** [December 7, 2021, 9:44pm UTC](https://forum.inductiveautomation.com/t/unable-to-close-filechannel-opened-with-nio/53861 "2021-12-07T21:44:30Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![jespinmartin1](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/jespinmartin1/32/57175_2.png) [@jespinmartin1](https://forum.inductiveautomation.com/u/jespinmartin1)\
**Post date:** [December 7, 2021, 9:44pm UTC](https://forum.inductiveautomation.com/t/unable-to-close-filechannel-opened-with-nio/53861/1 "2021-12-07T21:44:30Z")

</div>

I’m running a script where I want to get byte channel from file. Everything works fine, “apparently”. because when ever I try to delete the file I’m getting this

![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/1/6/1682bbf773f7644573095820908fd3283cd3f12b.png)

Of course I’m closing the channel

```auto
path = Paths.get("C:\\file.xlsx")
byteChannel = Files.newByteChannel(path, StandardOpenOption.READ)
byteBuffer = byteChannel.map(FileChannel.MapMode.READ_ONLY, 0, byteChannel.size())
byteChannel.close()

```

I’m able to delete the file only after closing the designer.

Does Ignition fully supports nio package?  
Any Java Pros Advices are appreciated!

---

<div class="post-metadata">

**Author:** ![Kevin.Herron](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/kevin.herron/32/7259_2.png) [@Kevin.Herron](https://forum.inductiveautomation.com/u/Kevin.Herron)\
**Post date:** [December 7, 2021, 9:48pm UTC](https://forum.inductiveautomation.com/t/unable-to-close-filechannel-opened-with-nio/53861/2 "2021-12-07T21:48:21Z")

</div>

Try `MapMode.PRIVATE` instead?

---

<div class="post-metadata">

**Author:** ![jespinmartin1](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/jespinmartin1/32/57175_2.png) [@jespinmartin1](https://forum.inductiveautomation.com/u/jespinmartin1)\
**Post date:** [December 7, 2021, 9:51pm UTC](https://forum.inductiveautomation.com/t/unable-to-close-filechannel-opened-with-nio/53861/3 "2021-12-07T21:51:03Z")

</div>

Got a little hope that your advice might work, but

```auto
java.nio.channels.NonWritableChannelException: java.nio.channels.NonWritableChannelException

```

---

<div class="post-metadata">

**Author:** ![jespinmartin1](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/jespinmartin1/32/57175_2.png) [@jespinmartin1](https://forum.inductiveautomation.com/u/jespinmartin1)\
**Post date:** [December 7, 2021, 10:04pm UTC](https://forum.inductiveautomation.com/t/unable-to-close-filechannel-opened-with-nio/53861/4 "2021-12-07T22:04:03Z")

</div>

Also tried to close the channel from `io.RandomAccessFile`. Same behavior.  
When doing the mapping with `MapMode.PRIVATE`. Same exception.

---

<div class="post-metadata">

**Author:** ![Kevin.Herron](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/kevin.herron/32/7259_2.png) [@Kevin.Herron](https://forum.inductiveautomation.com/u/Kevin.Herron)\
**Post date:** [December 7, 2021, 10:05pm UTC](https://forum.inductiveautomation.com/t/unable-to-close-filechannel-opened-with-nio/53861/5 "2021-12-07T22:05:56Z")

</div>

Do you _have_ to use a memory mapped file for some reason?

These work in a OS-dependent manner and the memory/file isn’t released until the buffer is GC’d. Your channel close is meaningless because you still have a buffer pointing to memory the file has been mapped to.

---

<div class="post-metadata">

**Author:** ![jespinmartin1](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/jespinmartin1/32/57175_2.png) [@jespinmartin1](https://forum.inductiveautomation.com/u/jespinmartin1)\
**Post date:** [December 7, 2021, 10:15pm UTC](https://forum.inductiveautomation.com/t/unable-to-close-filechannel-opened-with-nio/53861/6 "2021-12-07T22:15:21Z")

</div>

I was afraid to hear that.

The reason is because is the most efficient method to compare objects.

```auto
byteBuffer1.equals(byteBuffer2)

```

The idea is to determine if content of files are the same, beyond the comparison of file names. Trying to collect bytes has became challenging for xlsx big files, about 100Mb.

I was using `readAllBytes()` but from time to time I was getting `OutOfMemory` Exceptions.

Any advice you can provide?

---

<div class="post-metadata">

**Author:** ![Kevin.Herron](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/kevin.herron/32/7259_2.png) [@Kevin.Herron](https://forum.inductiveautomation.com/u/Kevin.Herron)\
**Post date:** [December 7, 2021, 10:29pm UTC](https://forum.inductiveautomation.com/t/unable-to-close-filechannel-opened-with-nio/53861/7 "2021-12-07T22:29:51Z")

</div>

Only briefly sanity checked:

```auto
    private static boolean compare(String f1, String f2) throws IOException {
        byte[] bs1 = new byte[1024];
        byte[] bs2 = new byte[1024];

        try (FileInputStream fis1 = new FileInputStream(f1);
             FileInputStream fis2 = new FileInputStream(f2)) {

            while (true) {
                int r1 = fis1.read(bs1);
                int r2 = fis2.read(bs2);
                if (r1 != r2) {
                    return false;
                }
                if (r1 == -1) {
                    return true;
                }
                if (!Arrays.equals(bs1, 0, r1, bs2, 0, r2)) {
                    return false;
                }
            }
        }
    }

```

You’d want to maybe play with the buffer size.

---

<div class="post-metadata">

**Author:** ![jespinmartin1](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/jespinmartin1/32/57175_2.png) [@jespinmartin1](https://forum.inductiveautomation.com/u/jespinmartin1)\
**Post date:** [December 7, 2021, 10:42pm UTC](https://forum.inductiveautomation.com/t/unable-to-close-filechannel-opened-with-nio/53861/8 "2021-12-07T22:42:51Z")

</div>

Let me translate it to Jython and give it a test.

I also tried FileInputStream() but the reason why I stopped using it is because nio.Files `isReabled()` is saying `False`. Even after closing the stream.

But, also, I’ll retry.

Any chance to notify the GC to trigger manually?

Thanks for the knowledge!

---

<div class="post-metadata">

**Author:** ![Kevin.Herron](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/kevin.herron/32/7259_2.png) [@Kevin.Herron](https://forum.inductiveautomation.com/u/Kevin.Herron)\
**Post date:** [December 7, 2021, 10:44pm UTC](https://forum.inductiveautomation.com/t/unable-to-close-filechannel-opened-with-nio/53861/9 "2021-12-07T22:44:33Z")

</div>

Not reliably and you’d have to trigger it in a separate script invocation after your first had gone out of scope.

Using memory mapped files just so you can do a comparison is over kill.

---

<div class="post-metadata">

**Author:** ![jespinmartin1](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/jespinmartin1/32/57175_2.png) [@jespinmartin1](https://forum.inductiveautomation.com/u/jespinmartin1)\
**Post date:** [December 7, 2021, 10:53pm UTC](https://forum.inductiveautomation.com/t/unable-to-close-filechannel-opened-with-nio/53861/10 "2021-12-07T22:53:27Z")

</div>

Right, I was delighted by the speed of mapped files using this approach.

Just an additional question, How much time would take the GC to act over these files. About 20 mins according to this graph maybe? or that is not even related?

![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/3/5/3569ff15ce52ff105569d11c882579e8a34f7953.png)

---

<div class="post-metadata">

**Author:** ![Kevin.Herron](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/kevin.herron/32/7259_2.png) [@Kevin.Herron](https://forum.inductiveautomation.com/u/Kevin.Herron)\
**Post date:** [December 7, 2021, 10:59pm UTC](https://forum.inductiveautomation.com/t/unable-to-close-filechannel-opened-with-nio/53861/11 "2021-12-07T22:59:07Z")

</div>

Maybe, but there could be smaller collections happening in between the big ones that don’t register on the graph. You’d have to turn on GC logging to see when it’s actually happening. And even then it would vary depending on what the gateway is up to.

You can _request_ a GC be done by calling `System.gc()`.

I’m curious what the performance difference between the regular code with varying buffer sizes and the memory mapped files is.

edit: comparing two equal 105MB files (worst case is when they are equal) with varying buffer sizes:

```auto
true
bufferSize=1024 took 1015ms
true
bufferSize=2048 took 456ms
true
bufferSize=4096 took 261ms
true
bufferSize=8192 took 140ms
true
bufferSize=16384 took 83ms
true
bufferSize=32768 took 54ms
true
bufferSize=65536 took 38ms
true
bufferSize=131072 took 31ms
true
bufferSize=262144 took 30ms
true
bufferSize=524288 took 36ms
true
bufferSize=1048576 took 85ms

```

---

<div class="post-metadata">

**Author:** ![jespinmartin1](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/jespinmartin1/32/57175_2.png) [@jespinmartin1](https://forum.inductiveautomation.com/u/jespinmartin1)\
**Post date:** [December 7, 2021, 11:48pm UTC](https://forum.inductiveautomation.com/t/unable-to-close-filechannel-opened-with-nio/53861/12 "2021-12-07T23:48:18Z")

</div>

Shouldn't be an statement fo r r2 != -1 as well, like below?

> [@Kevin.Herron](#):
>
> ```auto
> if (r1 == -1) {
> return true;
> 
> ```

Good, the script works but I'm having way worst performance compared to your results (buffer = 262144). Way worst, like 30 seconds hehe.  
Increasing the buffer to 2^23 did not make a huge difference.

Running from script console, designer with 4GB memory

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [December 7, 2021, 11:51pm UTC](https://forum.inductiveautomation.com/t/unable-to-close-filechannel-opened-with-nio/53861/13 "2021-12-07T23:51:38Z")

</div>

Kevin was almost certainly running from a local SSD, as his time implies a drive sequential rate of \>315MB/sec.

(The extra comparison isn’t needed because r1 and r2 are known to be equal at that point.)

(Hmm. Kevin, did you flush your drive cache between runs?)

---

<div class="post-metadata">

**Author:** ![Kevin.Herron](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/kevin.herron/32/7259_2.png) [@Kevin.Herron](https://forum.inductiveautomation.com/u/Kevin.Herron)\
**Post date:** [December 8, 2021, 12:03am UTC](https://forum.inductiveautomation.com/t/unable-to-close-filechannel-opened-with-nio/53861/14 "2021-12-08T00:03:06Z")

</div>

> [@pturmel](#):
>
> (Hmm. Kevin, did you flush your drive cache between runs?)

No, didn't do anything like that. I did a comparison against memory mapped files as well right after:

> memory mapped file comparison took 49ms

I am of course using a SSD.

And this was done on Windows, which is pretty shit compared to Linux or macOS when it comes to I/O performance, in my experience.

---

<div class="post-metadata">

**Author:** ![jespinmartin1](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/jespinmartin1/32/57175_2.png) [@jespinmartin1](https://forum.inductiveautomation.com/u/jespinmartin1)\
**Post date:** [December 8, 2021, 12:20am UTC](https://forum.inductiveautomation.com/t/unable-to-close-filechannel-opened-with-nio/53861/15 "2021-12-08T00:20:32Z")

</div>

Oh ok, you’re right.

Am doing this also in a SSD, but Windows. Can result vary that much based on OS?

Are you getting non satisfactorily results maybe?  
Assuming you also did testing.

---

<div class="post-metadata">

**Author:** ![jespinmartin1](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/jespinmartin1/32/57175_2.png) [@jespinmartin1](https://forum.inductiveautomation.com/u/jespinmartin1)\
**Post date:** [December 8, 2021, 12:26am UTC](https://forum.inductiveautomation.com/t/unable-to-close-filechannel-opened-with-nio/53861/16 "2021-12-08T00:26:13Z")

</div>

If you are running on any java interpreter different of Ignition and on any OS different from Windows.  
Those seems to be biggest variables for me.

May I ask, Do you have dates cells, bools, long and formulas on your excel files?  
Your PC specs maybe…

---

<div class="post-metadata">

**Author:** ![Kevin.Herron](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/kevin.herron/32/7259_2.png) [@Kevin.Herron](https://forum.inductiveautomation.com/u/Kevin.Herron)\
**Post date:** [December 8, 2021, 12:28am UTC](https://forum.inductiveautomation.com/t/unable-to-close-filechannel-opened-with-nio/53861/17 "2021-12-08T00:28:45Z")

</div>

I ran it using JDK 11 on Windows 10. Not through Jython. I didn’t use an Excel file, the contents of the shouldn’t matter.

![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/e/e/eea5defa0c824307b476b6c369df5c975adf8d00.png)

---

<div class="post-metadata">

**Author:** ![Kevin.Herron](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/kevin.herron/32/7259_2.png) [@Kevin.Herron](https://forum.inductiveautomation.com/u/Kevin.Herron)\
**Post date:** [December 8, 2021, 12:39am UTC](https://forum.inductiveautomation.com/t/unable-to-close-filechannel-opened-with-nio/53861/18 "2021-12-08T00:39:03Z")

</div>

Mine is fast in Jython code too… maybe you did something slow in your translation? Post the code you ended up with?

---

<div class="post-metadata">

**Author:** ![jespinmartin1](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/jespinmartin1/32/57175_2.png) [@jespinmartin1](https://forum.inductiveautomation.com/u/jespinmartin1)\
**Post date:** [December 8, 2021, 12:53am UTC](https://forum.inductiveautomation.com/t/unable-to-close-filechannel-opened-with-nio/53861/19 "2021-12-08T00:53:26Z")

</div>

mmm, this are my specs for now

 ![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/d/5/d579df5821f4a4007cb6d89e63467d0d31fe6f73.png)  
8 RAM

That is the code, do you see something maybe I don’t

```auto
then = system.date.now()
buffer = bytearray(2**23)
path1 = Paths.get("C:\\fileA.xlsx")
path2 = Paths.get("C:\\fileB.xlsx")
fileInputStream1 = FileInputStream(path1.toFile())
fileInputStream2 = FileInputStream(path2.toFile())
same = False
while True:
	read1 = fileInputStream1.read(buffer)
	read2 = fileInputStream2.read(buffer)
	if read1 != read2:
		break
	if read1 == -1:
		same = True
		break
	if not Arrays.equals(buffer, 0, read1, buffer, 0, read2):
		break
		
fileInputStream1.close()
fileInputStream2.close()
now = system.date.now()
print same
print system.date.millisBetween(then,now),'millis'

```

---

<div class="post-metadata">

**Author:** ![Kevin.Herron](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/kevin.herron/32/7259_2.png) [@Kevin.Herron](https://forum.inductiveautomation.com/u/Kevin.Herron)\
**Post date:** [December 8, 2021, 12:57am UTC](https://forum.inductiveautomation.com/t/unable-to-close-filechannel-opened-with-nio/53861/20 "2021-12-08T00:57:30Z")

</div>

Use `jarray` instead of `bytearray`:

```auto
buffer = jarray.zeros(262144, "b")

```

and then fix the fundamental flaw in your code where you read the files into the same buffer.

[Next page](https://forum.inductiveautomation.com/t/unable-to-close-filechannel-opened-with-nio/53861.md?page=2)
