File lock failure

  • Thread starter Thread starter Gary Nelson
  • Start date Start date
G

Gary Nelson

Anyone have any idea why this code does not work?

FileOpen(1, "c:\JUNK\MYTEST.TXT", OpenMode.Binary,
OpenAccess.ReadWrite, OpenShare.Shared)
Dim X As Integer
For X = 1 To 26
FilePut(1, Chr(X + 64))
Next
Lock(1, 5, 10)


When it hits the lock I get this message:

An unhandled exception of type 'System.ArgumentOutOfRangeException' occurred
in mscorlib.dll

Additional information: Non-negative number required.


I ran into this problem in a program I'm trying to port from VB6. I created
this simplified code to illustrate the problem.

Does VB.Net not support file locking????

Gary
 
Gary,

A couple of things I noticed

(a) Why would you lock a series of records you just inserted. It seems to
me that you would only lock these records if you were to edit them. Based
on your code it appears that the file is opened for sequential access and
according to the help:

"If the file has been opened for sequential input or output, Lock and Unlock
affect the entire file, regardless of the range specified by FromRecord and
ToRecord."

If you change your code to open in Random mode you should not have a problem
locking

FileOpen(filenum, "c:\temp\mytest.txt", OpenMode.Random,
OpenAccess.ReadWrite, OpenShare.Shared)

(b) If you really need to lock records you may want to consider using a
database instead of a file.

Good Luck,
Dan
 
Hi Gary,

Thanks for using Microsoft MSDN Managed Newsgroup. My name is Peter, and I
will be assisting you on this issue.

First of all, I would like to confirm my understanding of your issue.
From your description, I understand that when you Open File as
OpenMode.Binary and want to lock the file from 5 to 10 record(byte). and
you get error.
Have I fully understood you? If there is anything I misunderstood, please
feel free to let me know.

I think this is by design, if you really want to do so, you may need to
open the file as OpenMode.Random as solex suggest.

Best regards,
Peter Huang
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.
 
Dan,
(a) Why would you lock a series of records you just inserted.

As I stated: "I ran into this problem in a program I'm trying to port from
VB6. I created
this simplified code to illustrate the problem."

The reason I inserted data was to illustrate that it wasn't an empty file,
or I wasn't trying to lock beyond the eof.
It seems to
me that you would only lock these records if you were to edit them.

Obviously. And only when multiple users are attacking the data
simultaneously.
Based
on your code it appears that the file is opened for sequential access

Wrong. Look again. The file is being opened for Binary access.
and
according to the help:

"If the file has been opened for sequential input or output, Lock and Unlock
affect the entire file, regardless of the range specified by FromRecord and
ToRecord."

If that were the case, Lock would lock the whole file, not return an error.
If you change your code to open in Random mode you should not have a problem
locking

Random mode won't do. I am dealing with binary data. I want to lock a series
of bytes, which the help files says CAN be done.
(b) If you really need to lock records you may want to consider using a
database instead of a file.

What I want can not be handled by Access nor SQL.

Gary
 
Peter,

Thanks for your answer.
First of all, I would like to confirm my understanding of your issue.
From your description, I understand that when you Open File as
OpenMode.Binary and want to lock the file from 5 to 10 record(byte). and
you get error.

Exactly. This is a simplified example of what I need to do, but if you
execute the code you will see what happens.
Have I fully understood you? If there is anything I misunderstood, please
feel free to let me know.

You have understood.
I think this is by design, if you really want to do so, you may need to
open the file as OpenMode.Random as solex suggest.

It is clearly NOT by design. The help file clearly states:

Parameters
FileNumber
Required. Any valid file number.
FromRecord
Optional. Number of the first record or byte to lock or unlock.
ToRecord
Optional. Number of the last record or byte to lock or unlock.
Note that it clearly mentions "first record or BYTE" and "last record or
BYTE"

Also further down in the help file, the example given is this:

FileOpen(1, "c:\people.txt", OpenMode.Binary)

Why would the example show OpenMode.Binary if Lock can not handle binary
files?

Also the help file mentions as exceptions the following:
Exceptions/Errors
Exception type Error number Condition
IOException 52 FileNumber does not exist.
IOException 54 File mode is invalid.


I am not getting either of these exceptions, therefore I assume that it must
be a bug in VB.Net.

And on the other hand Random is no good for my purpose. In the situation I
am working on right now I am dealing with a binary file which at a certain
position has a double precision number which must be locked, read, added to,
and unlocked.As the file is accessed by multiple users simultaneously. Any
failure on the lock will produce incorrect results, therefore not locking is
not an alternative.

By the way, this worked perfectly with VB6.

Gary
 
Gary Nelson said:
It is clearly NOT by design. The help file clearly states:

I can't help you, just want to let you know that I also think it is not by
design. I also think it should work. I don't know why the negative values
are calculated. It also works in VB6.
 
Does VB.Net not support file locking????

Just a thought, could the Lock method depend on the position of the file
pointer? Perhaps if you tried to seek back to the beginning of the file
before attempting the lock. Also, what if you close and then reopen the
file before attempting the lock.

Finally, I notice that your hardcoding the file handle. Perhaps it would
be batter to call freefile. Maybe file handle number 1 is already in use.
Have you verified that the file was inded created and the correct data
exists in it?

It looks like it should work the way you have it. Hope these ideas can
help a little.
 
Gary,

After looking further into this out of curiosity I decided to try the
example in the docs under "Lock, Unlock" and there is a problem in the docs,
they use the FilePut function incorrectly, at least according to the docs
the FilePut overloaded functions all begin with the FileNumber and in the
example they are using some record index.

I am also trying to read the data back but cannot seem to get it to work
according to the docs under "Seek" the FileGet is supposed to accept a
structure as a parameter but in my IDE I get the error "Overload Resolution
Failed" Sample provided below.

Anyway I have included a modified example that appears to work, I ran it
from 2 different project in the IDE and I can write records at the same time
as long as the recNum paramaters are different. If I attempt to write the
same record number an error is generated as expected.

Out of curiosity what is it that you are trying to do that a database could
not do?

Regards,
Dan

<Sample Code>

Structure Person
Dim Name As String
Dim ID As Integer
End Structure

Public Sub Test()
InsertData(1)
End Sub

Public Sub InsertData(ByVal recNum As Integer)
Dim x As New Person
x.Name = "Chuck Kiedra"
x.ID = 13
PutInLockedFile(recNum, x)
x = Nothing
End Sub

Public Sub PutInLockedFile(ByVal index As Integer, ByVal onePerson As
Person)
Try
Dim filenum As Integer = FreeFile()
If index > 1 Then index *= Len(onePerson)
FileOpen(filenum, "c:\temp\people.txt", OpenMode.Binary, _
OpenAccess.ReadWrite, OpenShare.Shared)
Lock(filenum, index)
FilePut(filenum, onePerson, index)
Unlock(filenum, index)
FileClose(filenum)
Catch ex As Exception
MsgBox(ex.ToString)
End Try
End Sub

Public Sub ReadData()
Dim onePerson As Person

Try
Dim filenum As Integer = FreeFile()
FileOpen(filenum, "c:\temp\people.txt", OpenMode.Binary, _
OpenAccess.ReadWrite, OpenShare.Shared)
Seek(filenum,1)
' the following line will not compile
FileGet(filenum, onePerson)
Debug.WriteLine(onePerson.ID, onePerson.Name)
FileClose(filenum)
Catch ex As Exception
MsgBox(ex.ToString)
End Try
End Sub

</Sample Code>
 
Dan,
I am also trying to read the data back but cannot seem to get it to work
according to the docs under "Seek" the FileGet is supposed to accept a
structure as a parameter but in my IDE I get the error "Overload Resolution
Failed" Sample provided below.

Option Strict Off
Anyway I have included a modified example that appears to work

The problem is that you are only locking the first byte, not the whole
series of bytes you are writing to.
Out of curiosity what is it that you are trying to do that a database could
not do?

There are a lot of things you can do much more efficiently with a binary
file than with a database.

If you want to add a lot of speed to your programs do a little experimenting
with binary files.

Gary
 
Chris,
Just a thought, could the Lock method depend on the position of the file
pointer?
No

Perhaps if you tried to seek back to the beginning of the file
before attempting the lock.

No. Besides the fact that it doesn't change a thing, it would be a waste of
tiime.
Also, what if you close and then reopen the
file before attempting the lock.

Another waste of time, which by the way does not make a bit of difference.
It still doesn't work.
Finally, I notice that your hardcoding the file handle. Perhaps it would
be batter to call freefile. Maybe file handle number 1 is already in use.

As I stated in my post: "I created this simplified code to illustrate the
problem."

If you examine the code, you'll see that no files are open. Besides, the
error is not produced when the file is opened. The error occurs on the lock.
Have you verified that the file was inded created and the correct data
exists in it?
Yes.

It looks like it should work the way you have it.

It should.
Hope these ideas can help a little.

Not much. Personally I think it's a bug in VB.Net.

Gary
 
Hello Gary,

Thanks for your feedback.

I just discussed with Peter on it. We agreed with you that this doesn't
seem like a by design issue. I can reproduce it on my side. The behavior is
different from the MSDN document. It should not cause exception error. I
have reported it to our product team and am waiting for their response on
it. I will get back here as soon as possible.

If you have any more concerns on it, please feel free to post here. Thanks
and have a good day.

Best regards,
Yanhong Huang
Microsoft Community Support

Get Secure! ¨C www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.
 
Thanks for the response, and I would really appreciate it if you could help
find a solution as I need this funcionality.

Gary
 
Hello Gary,

Please rest assure that I will do my best to help you on it. Now we are
working with product group on it. If there is any update, I will post it
here.

BTW, we can send post notify email if there is any useful reply to your
post in the newsgroup. If you want to receive it, you can register no spam
email alias at
http://support.microsoft.com/default.aspx?scid=/servicedesks/msdn/nospam.asp
&SD=msdn.

Thanks very much.

Best regards,
Yanhong Huang
Microsoft Community Support

Get Secure! ¨C www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.
 
Hello Gary,

We have verified that this is a bug in the VB.NET runtime. It should
happen only in binary mode. We see only two work-arounds for now:

1) For the portion in which you are changing the double precision number at
a certain position in this file, you could re-open a FileStream on the file
and use the FileStream+BinaryWriter to lock and write those bytes, instead
of the VB runtime functions.

2) We could loop through each of the bytes to lock and call
FileLock(FileNumber, BytePosition) on each byte individually. No, this is
not ideal, but since
a) The scenario seems to be that only a few bytes will be locked, and b)
assuming each process that tries to write to this portion of the file
always locks either the entire of the interesting portion or the first byte
of it before locking the others, then it should be guaranteed that no other
process can get the lock on that portion of the file. If these conditions
can't be guaranteed, then I would recommend #1.

The issue has been entered into our bug database and it is being
investigated by our product group. Thanks very much for your feedback. If
you have any more concerns on it, please feel free to post here.

Best regards,
Yanhong Huang
Microsoft Community Support

Get Secure! ¨C www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.
 
Hi Gary,

Is there any question on the feedback from product team? If you have any
more concerns on this problem, please feel free to post here. I will help
pass it to product group.

Thanks very much for participating the community.

Best regards,
Yanhong Huang
Microsoft Community Support

Get Secure! ¨C www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.
 
Back
Top