-1

I was making an file encryptor/decryptor and I encountered some problem of FSO.ReadAll not reading the whole file's content.

Below is the code:

Sub EncryptFile(file) 
    Set FSO = CreateObject("Scripting.FileSystemObject")
    Set readf = FSO.OpenTextFile(file, 1)
    c = readf.ReadAll
    readf.Close()
    Set readf = Nothing
    'MsgBox only shows the first 4 characters of the file. ("ÿØÿà")
    'Does ReadAll stop its reading when the character is unreadable for it?
    'n = MsgBox(c, , "")
    '^^^^^ Result: ÿØÿà
    '...more below, but no longer needed for the question
End Sub

MsgBox result:

MsgBox n result

File contents (yes, the file is .JPG):

File contents

What seems to be the problem? Is it because ReadAll stops reading because the next character would be unreadable for the encoding or something, or anything else?

Ansgar Wiechers
  • 193,178
  • 25
  • 254
  • 328
amegyoushi
  • 524
  • 4
  • 14
  • 2
    c strings are terminated by null your 5th character. PS `c` (a bstr where null has no meaning) does contain the whole file but any api calls expecting a string will terminate at the 5th character. – Noodles Jun 02 '19 at 06:28
  • So what should I do in order for the [NUL] character and the characters after it to be read? – amegyoushi Jun 02 '19 at 06:32
  • 3
    They are being read but can't be printed to anything expecting a cstr, all API calls. You obviously don't want to msgbox it. So what do you want to do with it. – Noodles Jun 02 '19 at 06:34
  • Well, it's because when you go deeper into my code, there is a loop part where the loop goes through each character and turn them into their ASCII form via `AscW` (`t=1 _ For i=1 To Len(c) Step 1 _ r=AscW(Mid(c,t,1))`). But since that it cannot be read, the length of `c` is the length of all the characters in the file, but when `Mid` tries to continue on (`t` increases in value by 1), when `t`'s value is now 5, it throws an error. – amegyoushi Jun 02 '19 at 06:44
  • 1
    Why use `ascw`? – Noodles Jun 02 '19 at 08:38
  • 1
    I wouldn't expect `OpenTextFile` to work reliably at all with a non-textfile. (Look for `ADODB.Stream` for this in vbscript.) – KekuSemau Jun 03 '19 at 11:22
  • @KekuSemau You can't go through the bytes in a stream in VBScript. You can treat strings as byte arrays with the proviso that it only works on Western languages. So setting locale to US English (and to ANSI) for reading and writing and for the program it's self will generally work. – Noodles Jun 03 '19 at 20:40
  • 1
    @Noodles your going to have to explain yourself, I’ve used `ADODB.Stream` to read raw binary many times. Binary support is poor in VBScript but not impossible. You are right though using `AscW()` makes no sense in this scenario and will likely lead to garbled results. – user692942 Jun 04 '19 at 07:43
  • 1
    @Lankymart You can read, write, convert, and assign to other things, but not edit in vbscript because it doesn't support bytes or bytes(), only arrays of variants containing a byte. – Noodles Jun 04 '19 at 07:50
  • @Noodles I know, but you said *”you can’t go through the bytes in a stream in vbscript”* which is incorrect because as you just stated *”You can read”*. This is why I asked you to explain further. – user692942 Jun 04 '19 at 07:53
  • You can read a file into a stream object, convert it, write it, but not edit it in VBScript. Although the sister languages can because they support byte arrays, that you can assign a stream to. – Noodles Jun 04 '19 at 07:56
  • @KekuSemau: `OpenTextFile` works fine, even for binary files. The problem is the implementation of `ReadAll`, can be fixed with `Read` – Zimba Oct 27 '20 at 02:15
  • @scriptmastere02: Try `OpenTextFile(file)` with `Read` instead. What program gave you that screenshot? Thanks. – Zimba Oct 27 '20 at 02:32

1 Answers1

0

ReadAll is not meant for reading binary files.

Try using the read function instead.

 Sub EncryptFile(file) 
    Set FSO = CreateObject("Scripting.FileSystemObject")
    Dim objFile: Set objFile = oFSO.GetFile(file)

    Set readf = FSO.OpenAsTextStream()
    c = readf.Read(objFile.Size)
    readf.Close()
    Set readf = Nothing
End Sub

See: Read and write binary file in VBscript

Mi Rey
  • 1