Qt中使用readline()复制文件时如何保留原始换行符?
解决Qt复制文件时无法保留原始换行符及编码的问题
你遇到的核心问题是文本模式下QTextStream会自动转换换行符,再加上编码设置不匹配,最终导致复制后的文件和原文件不一致。我给你两个针对性的解决方案:
方案一:二进制模式直接复制(推荐,完全保留原文件所有内容)
如果你的需求只是单纯复制文件,不需要对文本内容做编辑处理,直接用二进制模式读写字节是最稳妥的方式——不会修改任何换行符、编码或其他原始字节:
void testFile() { QFile inFile(":/testFile-ANSI-win.txt"); // 去掉QIODevice::Text,使用纯二进制只读模式 if (!inFile.open(QIODevice::ReadOnly)) { qWarning() << "Failed to open input file"; return; } QFile outFile("../testFile-ANSI-win-bak.txt"); if (!outFile.open(QIODevice::WriteOnly | QIODevice::Truncate)) { qWarning() << "Failed to open output file"; inFile.close(); return; } // 方式1:一次性读取所有内容(适合小文件) outFile.write(inFile.readAll()); // 方式2:分块读取(适合大文件,避免内存占用过高) // char buffer[4096]; // qint64 bytesRead; // while ((bytesRead = inFile.read(buffer, sizeof(buffer))) > 0) { // outFile.write(buffer, bytesRead); // } inFile.close(); outFile.close(); }
方案二:文本流模式下保留原始换行符(需处理编码)
如果必须用QTextStream处理文本内容,又要保留原始换行符和编码,需要注意两个关键点:
- 打开文件时不要用
QIODevice::Text模式(该模式会自动转换平台相关换行符) - 明确指定原文件的编码(你的原文件是Windows ANSI,通常对应GBK编码)
void testFile() { QFile inFile(":/testFile-ANSI-win.txt"); // 禁用Text模式,保持原始字节流格式 if (!inFile.open(QIODevice::ReadOnly)) { qWarning() << "Failed to open input file"; return; } QFile outFile("../testFile-ANSI-win-readline-bak.txt"); if (!outFile.open(QIODevice::WriteOnly | QIODevice::Truncate)) { qWarning() << "Failed to open output file"; inFile.close(); return; } QTextStream in(&inFile); // 原文件是Windows ANSI,设置对应编码(比如GBK,根据实际情况调整) in.setCodec("GBK"); QTextStream out(&outFile); // 如果要保留原编码,就设置和输入相同的编码;如果要转UTF-8,就设置UTF-8 // out.setCodec("GBK"); // 保留原编码 out.setCodec("UTF-8"); // 转UTF-8但保留原始换行符 // 读取全部内容并写入,因为没开Text模式,换行符不会被转换 out << in.readAll(); inFile.close(); outFile.close(); }
问题根源解释
QIODevice::Text模式的设计目的是跨平台统一换行符:读取时会把Windows的\r\n、Mac的\r转换成Qt内部的\n,写入时再把\n转换成当前平台的换行符。这显然会破坏你想要保留的原始换行符格式。- 你写入时设置了
UTF-8编码,但读取时QTextStream默认使用系统编码(Windows下是GBK),这会导致原ANSI文件的编码被转换,进一步加剧文件不一致的问题。
内容的提问来源于stack exchange,提问作者JosanSun
相关产品推荐
相关产品推荐

