0

I'd like to remove the last character off a large file. The restrictions are that:

  • the file has to be modified in-situ, without using the disk space required for a similar second file
  • it's a windows machine
  • I cannot copy any compiled code onto the machine so I cannot create a small c# program of c++ program to manipulate the file
  • this also means any non-native scripting is not available, like python.

As far as I know, this limits me to bat, VB (or JScript) but it does not look like there is a viable option in these. VB requires a TextStream to be created from a systemfile object, but then this stream I believe must be saved elsewhere, using diskspace.

Is there a way to do this simply?

Joel Coehoorn
  • 399,467
  • 113
  • 570
  • 794
Retiarius
  • 334
  • 2
  • 12
  • open, change, overwrite? – Alex K. Oct 06 '14 at 12:03
  • No you can't. It's actually a stupid question. You have access to most languages as .NET framework includes compilers. – Noodles Oct 06 '14 at 13:04
  • I apologize for it being a stupid question. Do you mean that it can't be done in a scripting language, or that is could be done if I had the ability to compile and then run the code on the machine? I thought that for a large file 10's of Gb, the standard text streams would not be able to hold them in memory and could not write to the file at the same time when the operation removes data rather than appending. I'm really just after a stream class that can do this or an alternative like reducing the file size by 1 byte. – Retiarius Oct 06 '14 at 13:47
  • What about powershell? Is that allowed? It's not included out of the box with Windows, but it is "native", in a sense. In some versions of Windows you even install it by adding a Windows feature, rather than by running an installer program. – Joel Coehoorn Oct 06 '14 at 14:20
  • I'm not sure if it's on the machine.. Probably not, given the policy. No installers, no exes allowed :( – Retiarius Oct 06 '14 at 15:33

1 Answers1

1

Following the idea from Noodles (of course you need to have some .net framework version installed), you can try this

(save as trim.cmd and call as trim.cmd "fileToTrim.dat")

@if (@this==@isBatch) @then
@echo off
    setlocal enableextensions disabledelayedexpansion

    rem check arguments
    set "fileToTrim=%~1"
    if not exist "%fileToTrim%" goto :eof

    rem search for a valid framework version
    set "frameworks=%SystemRoot%\Microsoft.NET\Framework"
    set "jsc="
    for /f "tokens=* delims=" %%a in (
        'dir /b /a:d  /o:-n "%frameworks%\v*"'
    ) do if not defined jsc if exist "%frameworks%\%%a\jsc.exe" set "jsc=%frameworks%\%%a\jsc.exe"

    if not defined jsc goto :eof

    set "executable=%~dpn0.%random%.exe"
    %jsc% /nologo /out:"%executable%" "%~f0"
    if exist "%executable%" (
        "%executable%" "%fileToTrim%"
        del "%executable%" >nul 2>nul 
    )
    endlocal
    exit /b 0
@end
import System;
import System.IO;

var arguments:String[] = Environment.GetCommandLineArgs();

    if (arguments.length > 1) {
        var fi:FileInfo = new FileInfo(arguments[1]);
        var fs:FileStream = fi.Open(FileMode.Open);
        fs.SetLength (
            Math.max(0, fi.Length - 1)
        );
        fs.Close();
    };

This is far from efficient, the jscript code is compiled each time. Better directly write the program, compile and use. But just as an example ...

MC ND
  • 69,615
  • 8
  • 84
  • 126
  • Great - this is good as all the code can be seen before it is run. I did not know this could be done in the same file and run as a single command - Thanks! – Retiarius Oct 06 '14 at 15:27
  • Just to fill some gaps in my knowledge, I have been using JScript with cscript.exe which depends on functions like var fs = new ActiveXObject("Scripting.FileSystemObject"); - is the Filestream class above available with cscript? – Retiarius Oct 06 '14 at 17:18
  • @Retiarius, no. If you read the batch part, you will see that the code is calling a compiler (`jsc.exe`), not the script host (`cscript` or `wscript`). The code is written in JScript.Net, part of the .Net framework the same as VB.Net of C#. The file is formated to get that the compiler ignores the batch part and only compiles the JScript.Net. – MC ND Oct 06 '14 at 18:16
  • Ok, this is as I thought - I understand that this is compiling .Net using a .Net compiler. I suspected that JScript and VB as I was using it as a scripted language did not cover this. Thanks for taking time to answer more for this question! – Retiarius Oct 06 '14 at 18:46