views:

85

answers:

2

This is a method in ASP Classic that saves a file to disk. It takes a very long time but I'm not sure why. Normally, I wouldn't mind so much, but the files it handles are pretty large so need this needs to faster than 100kB a second save. Seriously slow. (old legacy system, band aid fix till it gets replaced...)

Public Sub SaveToDisk(sPath)
        Dim oFS, oFile
        Dim nIndex

        If sPath = "" Or FileName = "" Then Exit Sub

        If Mid(sPath, Len(sPath)) <> "\" Then sPath = sPath & "\"  '"

        Set oFS = Server.CreateObject("Scripting.FileSystemObject")
        If Not oFS.FolderExists(sPath) Then Exit Sub

        Set oFile = oFS.CreateTextFile(sPath & FileName, True)

        For nIndex = 1 to LenB(FileData)
            oFile.Write Chr(AscB(MidB(FileData,nIndex,1)))
        Next

        oFile.Close
    End Sub

I'm asking because there are plenty of WTF's in this code so I'm fighting those fires while getting some help on these ones.

+1  A: 

I don't see your definition for "FileData" anywhere in your code - where is this coming from? Is there a reason you're writing it to disk a single character at a time? I'd suspect this is your problem - writing 100K of data takes 100K trips through this loop, which could be the reason for your slowdown. Why can't you replace the write loop at the bottom:

For nIndex = 1 to LenB(FileData)
    oFile.Write Chr(AscB(MidB(FileData,nIndex,1)))
Next

with a single statement to write the file all at once?

oFile.Write FileData
rwmnau
-1. This will corrupt the data. The OP has posted a very niave solution to uploading arbitary files to an ASP server where third-party dlls are not present to assist. The problem with your solution is that the `Write` method will attempt to map Unicode to an ANSI codepage where what is really desired is the storage of the content verbatim.
AnthonyWJones
With regard to this unicode vs ansi thing, I solve this using a simple lookup table (Jscript):var unicodeToAnsi = {8364: 128, 129: 129, 8218: 130, 402: 131,8222: 132, 8230: 133, 8224: 134, 8225: 135,710: 136, 8240: 137, 352: 138, 8249: 139,338: 140, 141: 141, 381: 142, 143: 143,144: 144, 8216: 145, 8217: 146, 8220: 147,8221: 148, 8226: 149, 8211: 150, 8212: 151,732: 152, 8482: 153, 353: 154, 8250: 155,339: 156, 157: 157, 382: 158, 376: 159};
thomask
A: 

What you should do is read the binary request into an ADODB.Stream object and convert it to plain ASCII text in a single fast step.

Set objStream = Server.CreateObject("ADODB.Stream")

    objStream.Type = 1
    objStream.Open
    objStream.Write Request.BinaryRead(Request.TotalBytes)
    objStream.Position = 0
    objStream.Type = 2
    objStream.Charset = "ISO-8859-1"

    FormData = objStream.ReadText

    objStream.Close

Set objStream = Nothing

Notice how the variable FormData now contains the form data as text. Then you parse this text and locate the start and length of each file, and use ADODB.Stream CopyTo method to extract the specific portion of the file and save it do disk.

thomask
Cheers for that, I will have a go at it soon
burnt_hand