The day before yesterday, I encountered the problem of appending text in the middle of a file. I also read some Article I did some experiments and had some insights on the file append method proposed by yuweng: the first method is to expand the end of the file, and the content length is not limited; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - This problem is easy to solve. You only need to add the append flag when setting filemode. The Code is as follows: Filestream FS = new filestream ("F: \ test.txt", filemode. append, fileaccess. Write ); String STR = "\ n Chinese string NUL civilian 1 3 in total and National mailto :#! @! /N "; FS. Write (encoding. getencoding ("gb2312"). getbytes (STR), 0, encoding. getencoding ("gb2312"). getbytecount (STR )); FS. Close (); FS. Dispose (); If the appended content contains Chinese characters, the correct encoding format should be used; otherwise, garbled characters may occur. As you can see, the STR content is appended to the end of the file. The second type is equal to the byte replacement operation, and the location is not limited; - - - - - - - - - - - - - - - - - - - - - - - - - - - - To implement this replacement, you need to use the seek method of the file stream. The description is as follows: public override long seek ( Long offset, Seekorigin Origin ) Offset Start searching from this point relative to the origin. Origin Use a value of the seekorigin type to specify the start position, end position, or current position as the reference point of the origin. The second parameter can have three values: Member Name Description Begin specifies the beginning of the stream. Current specifies the current position in the stream. End specifies the end of the stream. For example: FS. Seek (41, seekorigin. Begin ); Set the position in the stream to 41 bytes from the beginning of the stream. Example: Using (filestream FS = new filestream ("F: \ test.txt", filemode. Open, fileaccess. Write, fileshare. None )) { FS. Seek (41, seekorigin. Begin ); String str1 = "888888888888888888888888888888888888888 \ r \ n "; FS. Write (encoding. getencoding ("gb2312"). getbytes (str1), 0, encoding. getencoding ("gb2312"). getbytecount (str1 )); } After the seek statement, the position in the stream is determined to be 41 bytes offset from the beginning of the stream, and then the STR content is written. Result: but we can see in the figure that there are only 39 "1" in the first line. Why is the position after the 41-byte offset the first character in the second line? This is because of line breaks. Original Because, we can use the hex format of UE to understand it: we can see that each time we wrap a line, there are two characters, "0x0d" and "0x0a", which are 10 and 13 in ASCII, that is, "\ r \ n" During encoding, so to replace 39 "2" in the second line, the position in the stream must be set to the 41-byte offset from the beginning (39 "1" plus a line feed return character, 41 characters in total ). if we want to replace 39 "8" characters in the last line, let's calculate the offset value? It should be 7*(39 + 2), of course, this is the number of bytes offset from the beginning of the stream, if we use seekorigin. it is convenient to specify the offset from the end of the stream. The last line has 39 "8" and line feed return characters, 41 bytes in total, so we use FS. seek ( - 41, seekorigin. end); you can set the position at the beginning of the 8th rows. sometimes, we cannot immediately obtain the location of the place to be replaced. In this way, we can search and find the location, such as the file above, if I want to replace 39 "5" with 39 "0 ", Program , To replace the data of this row, we also need to offset this position to the length of 41 bytes forward, and then we can write the data. The Code is as follows: Using (filestream FS = new filestream ("F: \ test.txt", filemode. Open, fileaccess. readwrite, fileshare. None )) { Int nrealread = 0; Int sum = 0; Byte [] bbuffer = new byte [41]; Do { // Read data Nrealread = FS. Read (bbuffer, 0, 41 ); Sum + = nrealread; // Output data String STR = encoding. Default. getstring (bbuffer, 0, nrealread ); // Get lazy. All 39 characters are the same :) If (Str. substring (0, 4) = "5555 ") { FS. Seek ( - 41, seekorigin. Current ); String str1 = "000000000000000000000000000000000000000 \ r \ n "; FS. Write (encoding. getencoding ("gb2312"). getbytes (str1), 0, encoding. getencoding ("gb2312"). getbytecount (str1 )); Break; } } While (nrealread = 41 ); }
You can also write fs. Seek (Sum - 41, seekorigin. begin); because the size of each read byte is accumulated in sum, in fact, the sum size and seekorigin. the current point is the same, and the length of the line offset is sum. - 41. The last one is that the location is not fixed and the number of bytes is uncertain. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - As for this, I don't think it is very likely to be used. Because you need to replace a part of the file, you need to know the text features to be replaced, so that you can find them through a row-by-row search, you can determine the location to replace. as for "uncertain number of bytes", I think Yu Weng refers to this situation: Replace by row, and I need to replace the data in this line, however, the length of the data after replacement is different from that before replacement. for example, the text before replacement: 11111 22222 33333 now you need to replace the text in the second line with 6 4, as shown below: 11111 444444 33333 in this case, if we only need to use overwriting, it is estimated that it will not be implemented, because more than the text will overwrite other texts. Let's make a simple experiment and use that text file, code: filestream FS = new filestream ("F: \ test.txt", filemode. open, fileaccess. readwrite, fileshare. readwrite ); Int nrealread = 0; Int sum = 0; Byte [] bbuffer = new byte [41]; Do { // Read data Nrealread = FS. Read (bbuffer, 0, 41 ); Sum + = nrealread; // Output data String STR = encoding. Default. getstring (bbuffer, 0, nrealread ); // Get lazy. All 39 characters are the same :) If (Str. substring (0, 4) = "5555 ") { FS. Seek (- 41, seekorigin. Current ); String str1 = "00000000000000000000000000000000000000099 \ r \ n "; Fs1.write (encoding. getencoding ("gb2312"). getbytes (str1), 0, encoding. getencoding ("gb2312"). getbytecount (str1 )); Break; } } While (nrealread = 41 ); FS. Close (); FS. Dispose (); the content of this replacement is 39 0 and 2 9 and line feed returns, length is 43, Ratio Original To 41 should contain 2 more characters. in this case, the replacement of the first line is changed to 39 0 and 2 9 and line feed return characters. In this case, the extra two characters will overwrite the first two characters of the second line. that is to say, replace to replace, more than the character always needs to overwrite other Original Character ,....... To solve this problem, I can only come up with a stupid method, that is, writing and reading, first reading the previous part of the text that I don't want to replace and then writing it to another text, write the replaced text, and then write the subsequent text ...... |
|