mirror of
https://github.com/SquidDev-CC/CC-Tweaked
synced 2025-10-28 04:17:38 +00:00
Rewrite file systems to use ByteChannels
This replaces the existing IMount openFor* method with openChannelFor* ones, which return an appropriate byte channel instead. As channels are not correctly closed when GCed, we introduce a FileSystemWrapper. We store a weak reference to this, and when it is GCed or the file closed, we will remove it from our "open file" set and ensure any underlying buffers are closed. While this change may seem a little odd, it does introduce some benefits: - We can replace JarMount with a more general FileSystemMount. This does assume a read-only file system, but could technically be used for other sources. - Add support for seekable (binary) handles. We can now look for instances of SeekableByteChannel and dynamically add it. This works for all binary filesystem and HTTP streams. - Rewrite the io library to more accurately emulate PUC Lua's implementation. We do not correctly implement some elements (most noticably "*n", but it's a definite improvement.
This commit is contained in:
@@ -13,6 +13,8 @@ import net.minecraft.world.World;
|
||||
import javax.annotation.Nonnull;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.channels.Channels;
|
||||
import java.nio.channels.ReadableByteChannel;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -72,7 +74,25 @@ public interface IMount
|
||||
* @param path A file path in normalised format, relative to the mount location. ie: "programs/myprogram".
|
||||
* @return A stream representing the contents of the file.
|
||||
* @throws IOException If the file does not exist, or could not be opened.
|
||||
* @deprecated Use {@link #openChannelForRead(String)} instead
|
||||
*/
|
||||
@Nonnull
|
||||
@Deprecated
|
||||
InputStream openForRead( @Nonnull String path ) throws IOException;
|
||||
|
||||
/**
|
||||
* Opens a file with a given path, and returns an {@link ReadableByteChannel} representing its contents.
|
||||
*
|
||||
* @param path A file path in normalised format, relative to the mount location. ie: "programs/myprogram".
|
||||
* @return A channel representing the contents of the file. If the channel implements
|
||||
* {@link java.nio.channels.SeekableByteChannel}, one will be able to seek to arbitrary positions when using binary
|
||||
* mode.
|
||||
* @throws IOException If the file does not exist, or could not be opened.
|
||||
*/
|
||||
@Nonnull
|
||||
@SuppressWarnings("deprecation")
|
||||
default ReadableByteChannel openChannelForRead( @Nonnull String path ) throws IOException
|
||||
{
|
||||
return Channels.newChannel( openForRead( path ) );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,8 @@ import net.minecraft.world.World;
|
||||
import javax.annotation.Nonnull;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.channels.Channels;
|
||||
import java.nio.channels.WritableByteChannel;
|
||||
|
||||
/**
|
||||
* Represents a part of a virtual filesystem that can be mounted onto a computer using {@link IComputerAccess#mount(String, IMount)}
|
||||
@@ -50,20 +52,54 @@ public interface IWritableMount extends IMount
|
||||
* @param path A file path in normalised format, relative to the mount location. ie: "programs/myprogram".
|
||||
* @return A stream for writing to
|
||||
* @throws IOException If the file could not be opened for writing.
|
||||
* @deprecated Use {@link #openStreamForWrite(String)} instead.
|
||||
*/
|
||||
@Nonnull
|
||||
@Deprecated
|
||||
OutputStream openForWrite( @Nonnull String path ) throws IOException;
|
||||
|
||||
/**
|
||||
* Opens a file with a given path, and returns an {@link OutputStream} for writing to it.
|
||||
*
|
||||
* @param path A file path in normalised format, relative to the mount location. ie: "programs/myprogram".
|
||||
* @return A stream for writing to. If the channel implements {@link java.nio.channels.SeekableByteChannel}, one
|
||||
* will be able to seek to arbitrary positions when using binary mode.
|
||||
* @throws IOException If the file could not be opened for writing.
|
||||
*/
|
||||
@Nonnull
|
||||
@SuppressWarnings("deprecation")
|
||||
default WritableByteChannel openStreamForWrite( @Nonnull String path ) throws IOException
|
||||
{
|
||||
return Channels.newChannel( openForWrite( path ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens a file with a given path, and returns an {@link OutputStream} for appending to it.
|
||||
*
|
||||
* @param path A file path in normalised format, relative to the mount location. ie: "programs/myprogram".
|
||||
* @return A stream for writing to.
|
||||
* @throws IOException If the file could not be opened for writing.
|
||||
* @deprecated Use {@link #openStreamForAppend(String)} instead.
|
||||
*/
|
||||
@Nonnull
|
||||
@Deprecated
|
||||
OutputStream openForAppend( @Nonnull String path ) throws IOException;
|
||||
|
||||
/**
|
||||
* Opens a file with a given path, and returns an {@link OutputStream} for appending to it.
|
||||
*
|
||||
* @param path A file path in normalised format, relative to the mount location. ie: "programs/myprogram".
|
||||
* @return A stream for writing to. If the channel implements {@link java.nio.channels.SeekableByteChannel}, one
|
||||
* will be able to seek to arbitrary positions when using binary mode.
|
||||
* @throws IOException If the file could not be opened for writing.
|
||||
*/
|
||||
@Nonnull
|
||||
@SuppressWarnings("deprecation")
|
||||
default WritableByteChannel openStreamForAppend( @Nonnull String path ) throws IOException
|
||||
{
|
||||
return Channels.newChannel( openForAppend( path ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the amount of free space on the mount, in bytes. You should decrease this value as the user writes to the
|
||||
* mount, and write operations should fail once it reaches zero.
|
||||
|
||||
Reference in New Issue
Block a user