mirror of
https://github.com/SquidDev-CC/CC-Tweaked
synced 2025-01-05 15:00:29 +00:00
Truncate files when writing them
This is performed by default, but as we don't pass any options, this flag is removed. Closes #75
This commit is contained in:
parent
67d5693d2a
commit
5fa01f8b96
12
.gitignore
vendored
12
.gitignore
vendored
@ -1,12 +1,12 @@
|
||||
build
|
||||
out
|
||||
run
|
||||
deploy
|
||||
/build
|
||||
/out
|
||||
/run
|
||||
*.ipr
|
||||
*.iws
|
||||
*.iml
|
||||
.idea
|
||||
.gradle
|
||||
luaj-2.0.3/lib
|
||||
luaj-2.0.3/*.jar
|
||||
/luaj-2.0.3/lib
|
||||
/luaj-2.0.3/*.jar
|
||||
*.DS_Store
|
||||
/test-files
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
package dan200.computercraft.core.filesystem;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
import dan200.computercraft.api.filesystem.IWritableMount;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
@ -13,12 +14,18 @@ import java.io.*;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.*;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.OpenOption;
|
||||
import java.nio.file.StandardOpenOption;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class FileMount implements IWritableMount
|
||||
{
|
||||
private static final int MINIMUM_FILE_SIZE = 500;
|
||||
private static final Set<OpenOption> READ_OPTIONS = Collections.singleton( StandardOpenOption.READ );
|
||||
private static final Set<OpenOption> WRITE_OPTIONS = Sets.newHashSet( StandardOpenOption.WRITE, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING );
|
||||
private static final Set<OpenOption> APPEND_OPTIONS = Sets.newHashSet( StandardOpenOption.WRITE, StandardOpenOption.CREATE, StandardOpenOption.APPEND );
|
||||
|
||||
private class WritableCountingChannel implements WritableByteChannel
|
||||
{
|
||||
@ -252,7 +259,7 @@ public class FileMount implements IWritableMount
|
||||
File file = getRealPath( path );
|
||||
if( file.exists() && !file.isDirectory() )
|
||||
{
|
||||
return FileChannel.open( file.toPath(), StandardOpenOption.READ );
|
||||
return FileChannel.open( file.toPath(), READ_OPTIONS );
|
||||
}
|
||||
}
|
||||
throw new IOException( "/" + path + ": No such file" );
|
||||
@ -386,8 +393,7 @@ public class FileMount implements IWritableMount
|
||||
m_usedSpace -= Math.max( file.length(), MINIMUM_FILE_SIZE );
|
||||
m_usedSpace += MINIMUM_FILE_SIZE;
|
||||
}
|
||||
return new SeekableCountingChannel( Files.newByteChannel( file.toPath(), StandardOpenOption.WRITE, StandardOpenOption.CREATE ),
|
||||
MINIMUM_FILE_SIZE );
|
||||
return new SeekableCountingChannel( Files.newByteChannel( file.toPath(), WRITE_OPTIONS ), MINIMUM_FILE_SIZE );
|
||||
}
|
||||
}
|
||||
|
||||
@ -409,8 +415,10 @@ public class FileMount implements IWritableMount
|
||||
else
|
||||
{
|
||||
// Allowing seeking when appending is not recommended, so we use a separate channel.
|
||||
return new WritableCountingChannel( Files.newByteChannel( file.toPath(), StandardOpenOption.WRITE, StandardOpenOption.CREATE, StandardOpenOption.APPEND ),
|
||||
Math.max( MINIMUM_FILE_SIZE - file.length(), 0 ) );
|
||||
return new WritableCountingChannel(
|
||||
Files.newByteChannel( file.toPath(), APPEND_OPTIONS ),
|
||||
Math.max( MINIMUM_FILE_SIZE - file.length(), 0 )
|
||||
);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
58
src/test/java/dan200/computercraft/core/FileSystemTest.java
Normal file
58
src/test/java/dan200/computercraft/core/FileSystemTest.java
Normal file
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2018. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.core;
|
||||
|
||||
import com.google.common.io.Files;
|
||||
import dan200.computercraft.api.filesystem.IWritableMount;
|
||||
import dan200.computercraft.api.lua.LuaException;
|
||||
import dan200.computercraft.core.apis.ObjectWrapper;
|
||||
import dan200.computercraft.core.apis.handles.EncodedWritableHandle;
|
||||
import dan200.computercraft.core.filesystem.FileMount;
|
||||
import dan200.computercraft.core.filesystem.FileSystem;
|
||||
import dan200.computercraft.core.filesystem.FileSystemException;
|
||||
import dan200.computercraft.core.filesystem.FileSystemWrapper;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class FileSystemTest
|
||||
{
|
||||
private static final File ROOT = new File( "test-files/filesystem" );
|
||||
|
||||
/**
|
||||
* Ensures writing a file truncates it.
|
||||
*/
|
||||
@Test
|
||||
public void testWriteTruncates() throws FileSystemException, LuaException, IOException
|
||||
{
|
||||
IWritableMount writableMount = new FileMount( ROOT, 1000000 );
|
||||
FileSystem fs = new FileSystem( "hdd", writableMount );
|
||||
|
||||
{
|
||||
FileSystemWrapper<BufferedWriter> writer = fs.openForWrite( "out.txt", false, EncodedWritableHandle::openUtf8 );
|
||||
ObjectWrapper wrapper = new ObjectWrapper( new EncodedWritableHandle( writer.get(), writer ) );
|
||||
wrapper.call( "write", "This is a long line" );
|
||||
wrapper.call( "close" );
|
||||
}
|
||||
|
||||
assertEquals( "This is a long line", Files.toString( new File( ROOT, "out.txt" ), StandardCharsets.UTF_8 ) );
|
||||
|
||||
{
|
||||
FileSystemWrapper<BufferedWriter> writer = fs.openForWrite( "out.txt", false, EncodedWritableHandle::openUtf8 );
|
||||
ObjectWrapper wrapper = new ObjectWrapper( new EncodedWritableHandle( writer.get(), writer ) );
|
||||
wrapper.call( "write", "Tiny line" );
|
||||
wrapper.call( "close" );
|
||||
}
|
||||
|
||||
assertEquals( "Tiny line", Files.toString( new File( ROOT, "out.txt" ), StandardCharsets.UTF_8 ) );
|
||||
}
|
||||
}
|
@ -0,0 +1,90 @@
|
||||
/*
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2018. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
|
||||
package dan200.computercraft.core.apis;
|
||||
|
||||
import dan200.computercraft.api.lua.ILuaContext;
|
||||
import dan200.computercraft.api.lua.ILuaObject;
|
||||
import dan200.computercraft.api.lua.ILuaTask;
|
||||
import dan200.computercraft.api.lua.LuaException;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class ObjectWrapper implements ILuaContext
|
||||
{
|
||||
private final ILuaObject object;
|
||||
private final String[] methods;
|
||||
|
||||
public ObjectWrapper( ILuaObject object )
|
||||
{
|
||||
this.object = object;
|
||||
this.methods = object.getMethodNames();
|
||||
}
|
||||
|
||||
private int findMethod( String method )
|
||||
{
|
||||
for( int i = 0; i < methods.length; i++ )
|
||||
{
|
||||
if( method.equals( methods[i] ) ) return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public boolean hasMethod( String method )
|
||||
{
|
||||
return findMethod( method ) >= 0;
|
||||
}
|
||||
|
||||
public Object[] call( String name, Object... args ) throws LuaException
|
||||
{
|
||||
int method = findMethod( name );
|
||||
if( method < 0 ) throw new IllegalStateException( "No such method '" + name + "'" );
|
||||
|
||||
try
|
||||
{
|
||||
return object.callMethod( this, method, args );
|
||||
}
|
||||
catch( InterruptedException e )
|
||||
{
|
||||
throw new IllegalStateException( "Should never be interrupted", e );
|
||||
}
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public Object[] pullEvent( @Nullable String filter )
|
||||
{
|
||||
throw new IllegalStateException( "Method should never yield" );
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public Object[] pullEventRaw( @Nullable String filter )
|
||||
{
|
||||
throw new IllegalStateException( "Method should never yield" );
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public Object[] yield( @Nullable Object[] arguments )
|
||||
{
|
||||
throw new IllegalStateException( "Method should never yield" );
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Object[] executeMainThreadTask( @Nonnull ILuaTask task )
|
||||
{
|
||||
throw new IllegalStateException( "Method should never yield" );
|
||||
}
|
||||
|
||||
@Override
|
||||
public long issueMainThreadTask( @Nonnull ILuaTask task )
|
||||
{
|
||||
throw new IllegalStateException( "Method should never queue events" );
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user