我需要读取txt文件的每一行,并将此行作为参数传递给方法。
我找到了这个例子:
LARGE_INTEGER byteOffset;
ntstatus = ZwCreateFile(&handle,
GENERIC_READ,
&objAttr, &ioStatusBlock,
NULL,
FILE_ATTRIBUTE_NORMAL,
0,
FILE_OPEN,
FILE_SYNCHRONOUS_IO_NONALERT,
NULL, 0);
if(NT_SUCCESS(ntstatus)) {
byteOffset.LowPart = byteOffset.HighPart = 0;
ntstatus = ZwReadFile(handle, NULL, NULL, NULL, &ioStatusBlock,
buffer, BUFFER_SIZE, &byteOffset, NULL);
if(NT_SUCCESS(ntstatus)) {
buffer[BUFFER_SIZE-1] = '\0';
DbgPrint("%s\n", buffer);
}
ZwClose(handle);
}
但是这会读取文件的所有内容而不是逐行。
关于这是怎么做的?
答案 0 :(得分:0)
读取所有要缓冲的文件或将其映射为部分。而不是执行下一个代码:
extern "C" PCSTR __fastcall findRN(SIZE_T cb, PCSTR sz);
void processLine(SIZE_T len, PCSTR line)
{
DbgPrint("%.*s\n", len, line);
}
NTSTATUS process(PCSTR buf, SIZE_T cb)
{
PCSTR end = buf + cb, line = buf;
while (buf = findRN(end - line, line))
{
processLine(buf - line, line);
line = buf + 2;
}
if (line != end)
{
processLine(end - line, line);
}
return 0;
}
在 c / c ++
上实施findRN
PCSTR __fastcall findRN(SIZE_T cb, PCSTR sz)
{
if (cb < 2)
{
return 0;
}
cb--;
do
{
if (*sz++ == '\r')
{
if (*sz == '\n')
{
return sz - 1;
}
}
} while (--cb);
return 0;
}
如果您需要/想要超快速最有效的实施,请在asm中执行此操作。例如x64:
findRN proc
cmp rcx,1
ja @@0
xor rax,rax
ret
@@0:
mov ax,0a0dh
xchg rdi,rdx
dec rcx
@@1:
repne scasb
jne @@2
cmp [rdi],ah
jne @@1
@@2:
sete al
dec rdi
movzx rax,al
neg rax
and rax,rdi
xchg rdi,rdx
ret
findRN endp
在x86代码上相同,只在注册名称中将 r 更改为 e
地图文件:
NTSTATUS process(POBJECT_ATTRIBUTES poa)
{
HANDLE hFile, hSection = 0;
IO_STATUS_BLOCK iosb;
NTSTATUS status = NtOpenFile(&hFile, FILE_GENERIC_READ, poa, &iosb,
FILE_SHARE_VALID_FLAGS, FILE_SYNCHRONOUS_IO_NONALERT);
if (0 <= status)
{
FILE_STANDARD_INFORMATION fsi;
if (0 <= (status = NtQueryInformationFile(hFile, &iosb, &fsi, sizeof(fsi), FileStandardInformation)))
{
if (fsi.EndOfFile.HighPart)
{
status = STATUS_FILE_TOO_LARGE;
}
else if (!fsi.EndOfFile.LowPart)
{
status = STATUS_MAPPED_FILE_SIZE_ZERO;
}
else
{
status = NtCreateSection(&hSection, SECTION_MAP_READ, 0, 0, PAGE_READONLY, SEC_COMMIT, hFile);
}
}
NtClose(hFile);
if (0 <= status)
{
PVOID BaseAddress = 0;
SIZE_T ViewSize = 0;
status = ZwMapViewOfSection(hSection, NtCurrentProcess(), &BaseAddress, 0,
0, 0, &ViewSize, ViewUnmap, 0, PAGE_READONLY);
NtClose(hSection);
if (0 <= status)
{
status = process((PCSTR)BaseAddress, fsi.EndOfFile.LowPart);
ZwUnmapViewOfSection(NtCurrentProcess(), BaseAddress);
}
}
}
return status;
}