Notes › Tech Notes › Split Text Into 43 Parts, Join It Back and 42 Bytes Are Gone, Every One of Them on a Newline

Split Text Into 43 Parts, Join It Back and 42 Bytes Are Gone, Every One of Them on a Newline

Splitting 300 lines into 43 parts of 7 lines and concatenating them back loses 42 bytes, and every lost byte is a newline sitting at a cut point. A 3 byte Chinese character is never split in half, but 0.1 per part blows through the budget and blank lines at the head of a part get swallowed.

Cuts land on newlines, not inside bytes

Take a plain text file of 300 lines, 2289 bytes altogether, split it at 7 lines per part, and the page reports 43 parts. Join those 43 parts head to tail in order and compare the result with the original file byte by byte: the reconstruction comes out 42 bytes shorter. Those 42 bytes were not eaten by packaging or by encoding. Every one of them sits on a cut, the newline wedged between neighbouring parts.

First, the reading people get wrong most often: the size branch on this page is not a hard byte cut. It first breaks the whole text into an array of lines on newlines, then adds line after line into the budget and closes a part once the budget is full, so a break can only land on a newline character and a 3 byte Chinese character cannot be split in half by construction. Pull the split function out of the template and run it unchanged: 240 mixed inputs through 3 modes, 720 splits, 1717 parts, 0 parts carrying the replacement character U+FFFD and 0 parts holding a half character.

One decisive sample settles it. The input is 100 copies of 测, then 1 newline, then 100 more copies, 201 code units and 601 bytes in all, since each 测 occupies 3 bytes. Set the size per part to 0.4 and the program floors the budget to 409 bytes, cutting 2 parts of exactly 100 code units and 300 bytes each. The first 2 bytes of both parts are E6 B5 and the last 2 bytes are B5 8B, so each side stays complete UTF-8 and the only thing missing is that 1 newline in the middle. For long Chinese prose, the line by line accumulation route used by Text Split is safe for multibyte characters.

Line and size: where the newline at a cut goes

Because a break always sits on a newline, one equation holds nearly every time: in line count and size modes the bytes summed over all parts equal the original bytes minus the part count less 1. The opening file, 2289 bytes cut into 43 parts, gives 2247, matching the part total measured after the merge, and the Chinese sample at 601 bytes cut into 2 parts comes out 1 short.

The same equation exposes how a whole line punches through the budget. At 0.1 per part the budget floors to 102 bytes while one line already runs 300, so the budget is smaller than a line. The program neither cuts the line nor raises an error, it seals every line as its own part, so 300 lines of 100 copies of 测 each, 90299 bytes, become 300 parts of 300 bytes, a part total of 90000 and 299 short. Squeeze 1000 copies of 测 onto one line with 1 per part and you still get 1 part of 3000 bytes. Splitting by size therefore guarantees only that a break lands on a whole line boundary, never that each part stays under the number you typed.

A subtler byte eater: when the buffer is empty the size branch assigns the current line directly, so blank lines at the head of a part are skipped. Feed in two blank lines, then abc, then a newline, then def, 9 bytes in all, and the split leaves 1 part whose content is 7 bytes. That gap breaks the equation, because what vanished is a line itself, not the newline at a cut.

Original2289 BParts total2247 BCut newline42 B300 lines, 7 per part, 43 parts

Figure 1: 2289 bytes cut into 43 parts total 2247 bytes, and the missing 42 bytes are all newlines at the cut points.

ModeWhere the cut landsPart total against original bytesSample
By line countnewlinepart count less 12289 cut into 43 parts loses 42
By sizenewlinepart count less 190299 cut into 300 parts loses 299
By delimiterthe delimiter itselfdelimiter width times part count less 153 cut into 4 parts loses 9

Delimiter: the separator enters no part

Delimiter mode has nothing to do with lines or bytes. It cuts on the delimiter, which the cut consumes, so neither neighbouring part contains it and the loss follows another equation. One sample runs 53 bytes: the three equals signs === give 4 parts and lose 9 bytes, and two newlines give 3 parts and lose 4 bytes. Rejoin the parts with the original delimiter and each group restores byte for byte, the same account as the line and size modes eating newlines.

Merging back: only 3 of the 18 groups match directly

Run 18 fixed samples, 6 inputs times 3 modes, through byte by byte comparison. Concatenating the parts with nothing added back equals the original input in only 3 groups, and the gap in the other 15 matches their cut counts exactly. Put 1 cut delimiter back and 17 groups agree; the one that never closes is the size case above that swallowed the leading blank lines. Scale up to the batch of 720 splits: plain concatenation matches in 360 groups, adding the delimiter back matches in 688, and by mode line count and delimiter each reach 240 while size manages only 208, leaving 32 groups that stay wrong even after the delimiter is restored. To recheck a seam I pass both texts through Text Compare and see at once whether the difference is newlines or content.

The byte count on screen need not be the real byte count

Confirm the ruler before settling any account. This page estimates size per code unit across three tiers: one 测 counts 3, a fullwidth comma 3, a 2 byte character 2, a BOM 3, all agreeing with standard encodings. Only supplementary plane characters are miscounted, because their two halves are each charged as 3 bytes, so one emoji reports 6 against a true 4, a fixed overcharge of 2 per code point. A part holding 150 such characters shows 900 B on screen while the file on disk is really 600 bytes. To cross check code units against bytes, run the text through Word Count first, then compare with what this page claims.

Display units walk base 1024 and the KB and MB tiers keep two decimals: 1023 still reads 1023 B, and only at 1024 does it jump to 1.00 KB; enter 100000 and the screen shows 97.66 KB, which decimal reckoning would have called 100 kB. Merge back with real bytes, never by subtracting these display values.

File names get no zero padding either: the prefix takes the index directly and then the extension, so at 1000 parts the index widths are 1 digit for 9 names, 2 digits for 90, 3 digits for 900 and 4 digits for 1, and the first four in lexicographic order are split_1.txt, split_10.txt, split_100.txt and split_1000.txt. The part number on screen pads to 3 digits and reads 001, which touches only the badge and never the file name. Bad parameters follow the same script: a line count per part of 0, blank, negative or a letter all report 请输入有效行数, the size cases report 请输入有效大小, a delimiter that escapes to nothing reports 请输入分隔符, and an empty input box reports 请输入文本. A line count per part of 301 or 1000, both above the 300 lines in the input, raises no error and yields 1 part.

A control experiment: what a hard byte cut would do

This one only keeps the risk apart from what the page actually does. Take 6 copies of 测, 18 bytes, and cut at byte position 4: decoding the left half yields 1 whole character plus 1 replacement character U+FFFD, and decoding that half in strict mode throws a type error. The size branch accumulates whole lines and never breaks inside a code unit, which is where the 0 half character parts out of 720 splits come from. So the bytes missing after a merge belong to newlines and delimiters, not to Chinese characters cut in half.

Frequently asked questions

Q: Does splitting by size guarantee that no part exceeds the number I entered?

No. The budget compares whole line accumulation, so when one line already exceeds it, 0.1 per part floors to 102 bytes against a 300 byte line, and nothing is truncated. Each line becomes one part, and the part total of 90000 against 90299 is still short by those 299 newlines.

Q: The merge back is shorter than the original file, so did I lose content?

Usually only a newline or a delimiter at each cut went missing. Put the matching delimiter back and 17 of the 18 groups restore byte for byte; the one that will not close is the size branch swallowing blank lines at the head of a part, so check whether the input starts with blank lines.

Q: Can I use the size shown on screen for byte arithmetic?

Not advisable. Supplementary plane characters are overcharged by a fixed 2 per code point, and the units are base 1024 with two decimals, so verify against the real byte reading instead of the displayed one.

📎 Related articles

You Paste 100 Fraction Rows and Row 45 Quietly Becomes 1/4: Who Owns the Minus Sign, Blank Lines and Big Numbers on This Page 2026-11-03 Paste 3. Start Into Markdown to HTML: Why Ordered List Numbering Only Honours the First Number 2026-11-03 Which Days Does the Crontab Expression 0 0 13 * 5 Actually Run: This Page Lists 2, Real cron Lists 62 2026-11-03 I Tested 16 Switch Combinations of an HTML Tag Stripper: It Reports 19 Tags but Deletes 148 Characters 2026-10-30 Linked Images Vanish When SVG Turns to PNG: A 594 Byte File Shows 3 Pictures in Preview and 1 in the Export 2026-10-30