简体   繁体   English

ReadFile Win32 API

[英]ReadFile Win32 API

i want to read a file.. but.. when i debug my program it runs but a pop up appears and says system programming has stopped working and in the console, it`s written that Press enter to close the program. 我想读一个文件..但..当我调试我的程序它运行但弹出窗口说系统编程已经停止工作,并在控制台,它写道,按Enter键关闭程序。 my code is :: 我的代码是::

// System Programming.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "iostream"
using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
    HANDLE hin;
    HANDLE hout;
    TCHAR buff[20]= {'q','2','3'};
    TCHAR buff2[20]={'a','v'};
    hin = CreateFile(_T("Abid.txt"),GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
    if(hin == INVALID_HANDLE_VALUE)
    {
        cout<<"error";
    }

    WriteFile(hin,buff,40,0,NULL);
    CloseHandle(hin);

    hout = CreateFile(_T("Abid.txt"),GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);

    if(hout == INVALID_HANDLE_VALUE)
    {
        cout<<"error";
    }

    ReadFile(hout,buff2,40,0,NULL);
    CloseHandle(hout);
    return 0;
}

According to MSDN, lpNumberOfBytesWritten paremeter can be NULL only when the lpOverlapped parameter is not NULL. 根据MSDN,只有当lpOverlapped参数不为NULL时,lpNumberOfBytesWritten参数才能为NULL。 So the calls should be 所以电话应该是

DWORD nWritten;
WriteFile(hin, buff, 40, &nWritten, NULL);

and

DWORD nRead;
ReadFile(hout, buff2, 40, &nRead, NULL);

Also, rename hin and hout . 另外,重命名hinhout

Others have already answered your question. 其他人已经回答了你的问题。 This is about the code. 这是关于代码的。

// Your code:
// System Programming.cpp : Defines the entry point for the console application.
//

Just remove that comment. 只需删除该评论即可。 It isn't true. 事实并非如此。 :-) The entry point for your program is where the machine code starts executing, and with the Microsoft toolchain it's specified by the /entry linker option. :-)程序的入口点是机器代码开始执行的地方,使用Microsoft工具链由/entry链接器选项指定。

Note that Microsoft's documentation is generally confused about entry points, eg it has always, one way or other, documented incorrect signature for entry point. 请注意,Microsoft的文档通常会对入口点感到困惑,例如,它始终以某种方式记录入口点的错误签名。

It's one of the most infamous Microsoft documentation errors, and, given that it's persisted, in various forms, for 15 years, I think it says something (not sure exactly what, though). 它是最臭名昭着的Microsoft文档错误之一,并且,鉴于它以各种形式持续存在了15年,我认为它说了些什么(不确定到底是什么)。

// Your code:
#include "stdafx.h"

You don't need this automatically generated header. 您不需要此自动生成的标头。 Instead use <windows.h> . 而是使用<windows.h> A minimal way to include <windows.h> for your program would be 为您的程序包含<windows.h>最小方法是

#undef  UNICODE
#define UNICODE
#include <windows.h>

For C++ in general you'll want to also make sure that STRICT and NOMINMAX are defined before including <windows.h> . 对于C ++,您通常还要确保在包含<windows.h>之前定义了STRICTNOMINMAX With modern tools at least STRICT is defined by default, but it doesn't hurt to make sure. 使用现代工具,默认情况下至少定义了STRICT ,但确保它并没有什么坏处。 Without it some of declarations won't compile with a C++ compiler, at least not without reinterpret casts, eg dialog procedures. 没有它,一些声明将无法使用C ++编译器进行编译,至少在没有重新解释强制转换的情况下,例如对话程序。

// Your code:
#include "iostream"
using namespace std;

Almost OK. 差不多好的。

Do this: 做这个:

#include <iostream>
using namespace std;

The difference is where the compiler searches for headers. 不同之处在于编译器搜索标头的位置。 With quoted name it searches in some additional places first (and that's all that the standard has to say about it). 使用引用的名称,它首先在一些其他位置搜索(这就是标准所说的所有内容)。 With most compilers those additional places include the directory of the including file. 对于大多数编译器,这些附加位置包括包含文件的目录。

// Your code:
int _tmain(int argc, _TCHAR* argv[])

Oh no! 不好了! Don't do this. 不要这样做。 It's a Microsoft "feature" that helps support Windows 9.x. 它是Microsoft“功能”,有助于支持Windows 9.x. And it's only relevant when you're using MFC linked dynamically and you're targeting Windows 9.x; 只有在您使用动态链接的MFC并且您的目标是Windows 9.x时,它才有意义; without MFC in the picture you'd just use the Microsoft Unicode layer. 在图片中没有MFC,您只需使用Microsoft Unicode层。

Area you really targeting Windows 9.x with an app using dynamically linked MFC? 您使用动态链接的MFC使用应用程序真正定位Windows 9.x的区域?

Instead, do ... 相反,做......

int main()

... which is standard, or use the Microsoft language extension ... ...这是标准的,或使用Microsoft语言扩展...

int wMain( int argc, wchar_t* argv[] )

... if you want to handle command line arguments the "easy" way. ...如果你想以“简单”的方式处理命令行参数。

// Your code:
{
    HANDLE hin;
    HANDLE hout;
    TCHAR buff[20]= {'q','2','3'};
    TCHAR buff2[20]={'a','v'};

The TCHAR stuff is just more of that MFC in Windows 9.x support stuff. TCHAR东西只是Windows 9.x中MFC的支持。

Apart from being totally unnecessary (presumably, you're not really targeting Windows 9.x, are you?), it hides your intention and hurts the eyes. 除了完全没必要之外(可能是你真的没有针对Windows 9.x,是吗?),它隐藏了你的意图并伤害了眼睛。

Did you mean ... 你的意思是 ...

char buff[20] = {'q', '2', '3'};

... perhaps? ... 也许?

// Your code:
    hin = CreateFile(_T("Abid.txt"),GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
    if(hin == INVALID_HANDLE_VALUE)
    {
        cout<<"error";
    }

As others have mentioned, OPEN_EXISTING isn't logical when you're creating the file, and the count pointer argument can't be 0 for your usage. 正如其他人所提到的,当您创建文件时, OPEN_EXISTING不合逻辑,并且计数指针参数不能为0。

When using <windows.h> , with UNICODE defined as it should be, the filename argument should be specifed as L"Abid.txt" . 使用<windows.h> ,如果定义了UNICODE ,则应将filename参数指定为L"Abid.txt"

Cheers & hth., 干杯&hth。,

The problem is that you're passing a NULL pointer in for the lpNumberOfBytesWritten / lpNumberOfBytesread parameter. 问题是您正在为lpNumberOfBytesWritten / lpNumberOfBytesread参数传递NULL指针。 While this is an optional parameter, there's a condition: 虽然这是一个可选参数,但有一个条件:

This parameter can be NULL only when the lpOverlapped parameter is not NULL 仅当lpOverlapped参数不为NULL时,此参数才可以为NULL

Also, you may have the size of your buffers wrong: 此外,您可能错误地调整了缓冲区的大小:

WriteFile(hin,buff,40,0,NULL);  // says that buff has 40 bytes

ReadFile(hout,buff2,40,0,NULL); // says that buff2 has 40 bytes

But if you're compiling for ANSI instead of UNICODE, these will only be 20 bytes in size. 但是如果你正在编译ANSI而不是UNICODE,那么它们的大小只有20个字节。

You should probably use sizeof(buff) and sizeof(buff2) instead. 您应该使用sizeof(buff)sizeof(buff2)代替。

Assuming your initial code attempts to create the file as a new file, then you cannot use OPEN_EXISTING , you have to use OPEN_ALWAYS (or some other creational variant) on this call. 假设您的初始代码尝试将文件创建为新文件,那么您不能使用OPEN_EXISTING ,您必须在此调用中使用OPEN_ALWAYS (或其他一些创建变体)。

The OPEN_EXISTING usage for readback will be OK. 用于回读的OPEN_EXISTING用法将正常。

btw once this is fixed the WriteFile calls causes an access violation, as you are trying to write more bytes that your array contains. 顺便说一下,一旦修复了WriteFile调用就会导致访问冲突,因为你试图写入数组包含的更多字节。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM