Laurent Rhelp
2024-May-21 09:29 UTC
[R] wrtiteBin in conjunction with seek : the position in the file is not good when writing
Dear RHelp-list, ?I want to write at a specific position in a file without reading all the file because it is very large and I cannot read it in my RAM. But I miss something about the use of the command writeBin in conjunction with seek. In the example bellow the seek commands works well with the readBin command but not with writeBin, the writeBin command write from the beginning of the file and not from the current position and however in the doculentation it is written: ? If the connection is open it is read/written from its current position. Thank you Best regards Laurent Here is the tiny example: The file_test.txt before: 1234567890 1234567890 The file_test.txt after: ?AA AA7890 1234567890 The file should have been like that: 123456 AA AA1234567890 ## open the file in read/write mode + binary fname <- file.path(".","txt","file_test.txt") con_in <- file(fname,"r+b") # move on 2 bytes pos <- seek(con_in,2,origin="start") # We have to repeat the command to return the good amount of read bytes print(paste0("pos is not equal to 2, pos = ",pos)) pos <- seek(con_in,2,origin="start") print(paste0("Now pos is equal to 2, pos = ",pos)) ## reading 3 characters bytes = readBin(con=con_in, what="raw",n = 3) my_number <- as.numeric(readBin(bytes,"character")) print(my_number) # we are on position 6 pos <- seek(con_in,0,origin="current") print(paste0("pos = ",pos)) bytes = readBin(con=con_in, what="raw",n = 1) my_number <- as.numeric(readBin(bytes,"character")) print(my_number) my_string <- charToRaw(sprintf(paste('%',3,'s',sep=''),"AA")) writeBin(? my_string, con=con_in, useBytes = FALSE) writeBin(? my_string, con=con_in, useBytes = FALSE) close(con_in)
Ivan Krylov
2024-May-21 10:15 UTC
[R] wrtiteBin in conjunction with seek : the position in the file is not good when writing
? Tue, 21 May 2024 11:29:33 +0200 Laurent Rhelp <laurentRHelp at free.fr> ?????:> pos <- seek(con_in,2,origin="start") > # We have to repeat the command to return the good amount of read > # bytes > print(paste0("pos is not equal to 2, pos = ",pos))That's because seek() returns the previous position ("before any move", the one that the help page calls "current"), not the one after the seek. Fortunately, calling seek(origin = "start") twice with the same offset doesn't break anything.> # we are on position 6 > pos <- seek(con_in,0,origin="current")That's strange. You started at offset 2 and read three bytes. You should be at offset 5 at this point. For me, seek() returns 5 here, not 6.> bytes = readBin(con=con_in, what="raw",n = 1)But after this, we should be on position 6.> writeBin(? my_string, con=con_in, useBytes = FALSE)It's described in help(seek) that R maintains two different pointers for reading and writing a file. You have been reading it, advancing the read pointer to 6, but the write pointer stayed at offset 0. Try seek(con_in, seek(con_in, 0, 'current', 'read'), 'start', 'write') to set the write pointer to the read pointer before issuing writes. This seems to give me the expected result. -- Best regards, Ivan
Possibly Parallel Threads
- wrtiteBin in conjunction with seek : the position in the file is not good when writing
- dplyr, group_by and selective action according to each group
- Question about ObjectSizeOffsetVisitor::visitGlobalVariable
- Removing a block of text within a string
- dplyr, group_by and selective action according to each group