|
-
Nov 28th, 2009, 03:35 PM
#1
Thread Starter
Lively Member
[RESOLVED] Write bytes to file at specified position.
Say I have 10 parts of a file. Each part is 10,000 bytes.
Now say I receive these parts out of order meaning I cannot simply just write them in order as I receive them, but I am able to detect what part it is.
If I received part 3 how would I write those bytes in the 20,000-30,000 byte section of a file?
-
Nov 28th, 2009, 03:42 PM
#2
Re: Write bytes to file at specified position.
Maybe you can create a stream and fill the 20000 first bytes with zeros or nulls, and after this add the 10000 bytes that you received...
Rate People That Helped You
Mark Thread Resolved When Resolved
-
Nov 28th, 2009, 04:13 PM
#3
Thread Starter
Lively Member
Re: Write bytes to file at specified position.
So say I receive part 3.
I write part 2 and 3 with zeroes and part 3 with the actual data.
I then receive part 1, how would I just change the first 10,000 bytes? And when I receive part 2 how would I just change the 10,000-20,000 bytes?
-
Nov 28th, 2009, 04:20 PM
#4
Re: Write bytes to file at specified position.
I never tried to do that but something like:
VB.NET Code:
Dim st As New IO.MemoryStream(30000) Dim byt(10000) As Byte Dim strDataReceuved(10000) As Byte st.Write(byt, 0, 10000) 'Bytes, Offset, NumBytes st.Write(strDataReceuved, 10000, 10000) ...
Rate People That Helped You
Mark Thread Resolved When Resolved
-
Nov 28th, 2009, 06:43 PM
#5
Re: Write bytes to file at specified position.
Open a FileStream, Seek to the appropriate position, Write the data. E.g.
vb.net Code:
Const BLOCK_SIZE As Integer = 10000 Dim blockIndex As Integer '0 for first block, 1 for second, etc. Dim data(BLOCK_SIZE - 1) As Byte 'Get data here. Using fs = IO.File.OpenWrite("file path here") fs.Seek(blockIndex * BLOCK_SIZE, IO.SeekOrigin.Begin) fs.Write(data, 0, BLOCK_SIZE) End Using
-
Dec 21st, 2009, 08:20 PM
#6
Thread Starter
Lively Member
Re: Write bytes to file at specified position.
Well this is a delayed response, but thanks for the help.
What am I doing wrong? I have purposely done the thread waits to simulate an out of order arrival.
vbnet Code:
'fnnn is a temp global filestream that is for the file I am writing to Using fs = File.OpenRead(filePath) If fs.CanRead Then Do Until totalRead = fs.Length read = fs.Read(buffer, 0, BYTES_TO_READ) ' sc.SendFile(uploadID, totalRead, read, buffer) Dim t As New test t.seek = totalRead t.amount = read t.data = buffer Dim t22 As New Thread(AddressOf t.send) t22.IsBackground = True t22.Start() totalRead += read Loop End If End Using Public Class test Public seek As Integer Public amount As Integer Public data() As Byte Public Sub send() Dim r As New Random Thread.Sleep(r.Next(100, 2000)) SyncLock fnnn fnnn.Seek(seek, IO.SeekOrigin.Begin) fnnn.Write(data, 0, amount) End SyncLock End Sub End Class
The above only works if the pieces of the file arrive in order. The file size mimics correctly but it is is corrupted.
-
Dec 22nd, 2009, 04:35 AM
#7
Re: Write bytes to file at specified position.
Are you saying that if you send one file, and then write that to the file, it doesn't work if the pieces don't arrive in order...
If that it's normal if you don't have anything that tells what piece belong to which position... but at beginning of the thread you said "I am able to detect what part it is", so what's the problem?
You have two options, use an auxiliar
Rate People That Helped You
Mark Thread Resolved When Resolved
-
Dec 22nd, 2009, 02:13 PM
#8
Thread Starter
Lively Member
Re: Write bytes to file at specified position.
Well I am asking why isn't the code I posted above not working. I am detecting where to start, how much I am writing and the data that is being wrote.
The problem is I am doing something wrong in it that is causing it to not work properly if it is out of order.
-
Dec 22nd, 2009, 05:32 PM
#9
Re: Write bytes to file at specified position.
If you expect to be able to seek to any position in the file then you have to have created the file to its full size at the outset. For instance, lets say that you have a 2K file and you send it in two batches. How can you write the second kilobyte first if you don't know the file that size?
-
Dec 22nd, 2009, 10:19 PM
#10
Thread Starter
Lively Member
Re: Write bytes to file at specified position.
So using the same code I have above I have just added this to the file creation process.
I have tried this:
vbnet Code:
Dim fff As New FileInfo(fp)
fnnn = File.Create("C:\" & fn, fff.Length)
and this, but still no success.
vbnet Code:
Dim fff As New FileInfo(fp)
fnnn = File.Create("C:\" & fn)
Dim b(fff.Length) As Byte
fnnn.Write(b, 0, fff.Length)
-
Dec 23rd, 2009, 04:56 PM
#11
Thread Starter
Lively Member
Re: Write bytes to file at specified position.
Ok, I wrote up something small to just try to fix this problem alone.
This only works if each file part arrives in correct order. For example it works perfectly if I add a messagebox at the end of the loop or remove the threading.
I'm not sure what I am doing wrong.
This is the code I have:
vbnet Code:
Imports System.IO Imports System.Threading Public Class Form1 Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click ofd.ShowDialog() 'Open file dialog start() End Sub Sub start() Const BYTES_TO_READ As Integer = 10000 'Max bytes to be read at one time Dim totalRead As Long = 0 'How many bytes have been read overall Dim read As Long = 0 'The bytes read in one 'reading' Dim buffer(BYTES_TO_READ - 1) As Byte 'Hold the bytes that are read Dim nf As FileStream = File.Create("C:\test\" & ofd.SafeFileName) 'Create the new file Using fs = File.OpenRead(ofd.FileName) 'Read through the file we are sending FileWrite.total = fs.Length 'Get the file size of the file we want to copy FileWrite.currentTotal = 0 Dim b(fs.Length) As Byte 'Create our initial file size for the new file nf.Write(b, 0, fs.Length) 'Write empty bytes to the new file so it equals the old files length Do Until totalRead = fs.Length 'Loop through the old file read = fs.Read(buffer, 0, BYTES_TO_READ) 'Read 10,000 bytes at a time Dim fw As New FileWrite(nf, totalRead, read, buffer) 'Initiate the filewrite class Dim t As New Thread(AddressOf fw.start) t.IsBackground = True t.Start() 'Start multithreading for it totalRead += read Loop End Using End Sub End Class Class FileWrite Public stream As FileStream 'Holds the stream to be writing to Public seek As Long 'Where to seek to in the file stream Public amount As Long 'How many bytes to write Public data() As Byte 'The data to be written Public Shared total As Long 'The file size of the file Public Shared currentTotal As Long 'How much has already been written to the file Sub New(ByVal fs As FileStream, ByVal SeekStart As Long, ByVal WriteAmount As Long, ByVal WriteData() As Byte) stream = fs seek = SeekStart amount = WriteAmount data = WriteData End Sub Sub start() SyncLock stream 'So multiple threads don't access at the same time stream.Seek(seek, SeekOrigin.Begin) 'Seek to the part of the file stream.Write(data, 0, amount) 'Write to the file currentTotal += amount 'Record how many bytes have been written If currentTotal = total Then 'If all bytes have been written close the file stream.Flush() stream.Close() End If End SyncLock End Sub End Class
Last edited by Disyne; Dec 23rd, 2009 at 05:15 PM.
-
Dec 23rd, 2009, 05:08 PM
#12
Re: Write bytes to file at specified position.
Maybe it's time to put some comments through your code so that you and others can quickly see what each part is intended to do, whether it actually does that and what parts may be missing.
-
Dec 23rd, 2009, 05:14 PM
#13
Thread Starter
Lively Member
Re: Write bytes to file at specified position.
-
Dec 23rd, 2009, 05:24 PM
#14
Re: Write bytes to file at specified position.
Code:
'create file name and location
Dim dsktpDir As String = Environment.GetFolderPath(Environment.SpecialFolder.Desktop)
Dim testFilePath As String = IO.Path.Combine(dsktpDir, "testfile.txt")
'open or create if it doesn't exist
Dim fsB As New FileStream(testFilePath, FileMode.OpenOrCreate, FileAccess.ReadWrite)
'check the length
If fsB.Length < 10 * 10000 Then
fsB.SetLength(10 * 10000)
End If
'write two bytes
Dim abyte As Byte = 85 'U
fsB.Seek(99998, SeekOrigin.Begin)
fsB.WriteByte(abyte)
abyte = 90 'Z
fsB.WriteByte(abyte)
'check
fsB.Seek(99998, SeekOrigin.Begin)
abyte = CByte(fsB.ReadByte)
fsB.Flush()
fsB.Close()
-
Dec 23rd, 2009, 06:52 PM
#15
Thread Starter
Lively Member
Re: Write bytes to file at specified position.
I have found out the problem.
Since the data was stored in an array, when I passed the array to my sub class in a worker thread by the time it got to writing the data the array itself already had its data replaced with new bytes.
So the fix was as easy as:
data = WriteData
to
data = WriteData.Clone()
Thank you everyone for your help.
Last edited by Disyne; Dec 23rd, 2009 at 06:57 PM.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|