FILE* 获取不到当前的文件名?或文件路径吗?

Sodino 2015-03-05 10:55:03
看FILE的头文件中有 _p参数含义是当前的位置
typedef	struct __sFILE {
unsigned char *_p; /* current position in (some) buffer */
... ...
... ...
}FILE;

代码fopen()一个文件,经调试 _p却是NULL,

FILE * tmp = fopen(str, "ra");
if (tmp != NULL) {
printf("tmp->_p:%s \n", tmp->_p);

fclose(tmp);
tmp = NULL;
} else {
printf("fopen %s fail. \n", str);
}


疑问:仅通过FILE* 是获取不到当前的文件名?或文件路径吗?
...全文
324 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
Sodino 2015-03-14
  • 打赏
  • 举报
回复
回帖都差强人意,把分散了吧
Braid_xiao 2015-03-08
  • 打赏
  • 举报
回复
_(:з」∠)_我在刚学到这里的时候,我考虑到路径问题,发现如果打开的文件是跟你生成的exe在同一个路径下,fopen(“filename.xxx……)就可以,否则就要绝对路径……不然它才不会去帮你找。 如果使用argc/argv[ ]也是相对路径,同求为什么
赵4老师 2015-03-08
  • 打赏
  • 举报
回复
Linux是开源的。
Sodino 2015-03-08
  • 打赏
  • 举报
回复
引用 5 楼 zhao4zhong1 的回复:
难者不会,会者不难!
#pragma comment(lib,"psapi")
#include <windows.h>
#include <stdio.h>
#include <tchar.h>
#include <string.h>
#include <psapi.h>
#include <io.h>
#define BUFSIZE 512
BOOL GetFileNameFromHandle(HANDLE hFile)
{
  BOOL bSuccess = FALSE;
  TCHAR pszFilename[MAX_PATH+1];
  HANDLE hFileMap;

  // Get the file size.
  DWORD dwFileSizeHi = 0;
  DWORD dwFileSizeLo = GetFileSize(hFile, &dwFileSizeHi);

  if( dwFileSizeLo == 0 && dwFileSizeHi == 0 )
  {
     _tprintf(TEXT("Cannot map a file with a length of zero.\n"));
     return FALSE;
  }

  // Create a file mapping object.
  hFileMap = CreateFileMapping(hFile,
                    NULL,
                    PAGE_READONLY,
                    0,
                    1,
                    NULL);

  if (hFileMap)
  {
    // Create a file mapping to get the file name.
    void* pMem = MapViewOfFile(hFileMap, FILE_MAP_READ, 0, 0, 1);

    if (pMem)
    {
      if (GetMappedFileNameA (GetCurrentProcess(),
                             pMem,
                             pszFilename,
                             MAX_PATH))
      {

        // Translate path with device name to drive letters.
        TCHAR szTemp[BUFSIZE];
        szTemp[0] = '\0';

        if (GetLogicalDriveStrings(BUFSIZE-1, szTemp))
        {
          TCHAR szName[MAX_PATH];
          TCHAR szDrive[3] = TEXT(" :");
          BOOL bFound = FALSE;
          TCHAR* p = szTemp;

          do
          {
            // Copy the drive letter to the template string
            *szDrive = *p;

            // Look up each device name
            if (QueryDosDevice(szDrive, szName, MAX_PATH))
            {
              size_t uNameLen = _tcslen(szName);

              if (uNameLen < MAX_PATH)
              {
                bFound = _tcsnicmp(pszFilename, szName, uNameLen) == 0
                         && *(pszFilename + uNameLen) == _T('\\');

                if (bFound)
                {
                  // Reconstruct pszFilename using szTempFile
                  // Replace device path with DOS path
                  TCHAR szTempFile[MAX_PATH];
                  sprintf(szTempFile,
                            TEXT("%s%s"),
                            szDrive,
                            pszFilename+uNameLen);
                  strcpy(pszFilename, szTempFile);
                }
              }
            }

            // Go to the next NULL character.
            while (*p++);
          } while (!bFound && *p); // end of string
        }
      }
      bSuccess = TRUE;
      UnmapViewOfFile(pMem);
    }

    CloseHandle(hFileMap);
  }
  _tprintf(TEXT("File name is %s\n"), pszFilename);
  return(bSuccess);
}

int _tmain(int argc, TCHAR *argv[])
{
    FILE *f;
    HANDLE hFile;

    if( argc != 2 )
    {
        _tprintf(TEXT("This sample takes a file name as a parameter.\n"));
        return 0;
    }
    f=fopen(argv[1],"r");
    if (NULL==f) return 0;
    hFile=(HANDLE)_get_osfhandle(fileno(f));
//  hFile = CreateFile(argv[1], GENERIC_READ, FILE_SHARE_READ, NULL,
//      OPEN_EXISTING, 0, NULL);

    if(hFile == INVALID_HANDLE_VALUE)
    {
        _tprintf(TEXT("CreateFile failed with %d\n"), GetLastError());
        return 0;
    }
    GetFileNameFromHandle( hFile );
    fclose(f);
    return 0;
}
//C:\test>test c:\windows\system32\kernel32.dll
//File name is C:\WINDOWS\system32\kernel32.dll
//
谢谢提供代码, 发现个问题,难道 _get_osfhandle是在windows.h里面? 那linux下的咋办呢?
ri_aje 2015-03-06
  • 打赏
  • 举报
回复
引用 4 楼 sodino 的回复:
[quote=引用 3 楼 ri_aje 的回复:] FILE 就管文件,不管路径名。
额..看了下java.io.File.java,路径名是java层面的数据管理了.... 那想追问,为何FILE->_p会是NULL呢? [/quote] 那是 implementation detail 啦,自己慢慢看源码吧。
赵4老师 2015-03-06
  • 打赏
  • 举报
回复
难者不会,会者不难!
#pragma comment(lib,"psapi")
#include <windows.h>
#include <stdio.h>
#include <tchar.h>
#include <string.h>
#include <psapi.h>
#include <io.h>
#define BUFSIZE 512
BOOL GetFileNameFromHandle(HANDLE hFile)
{
  BOOL bSuccess = FALSE;
  TCHAR pszFilename[MAX_PATH+1];
  HANDLE hFileMap;

  // Get the file size.
  DWORD dwFileSizeHi = 0;
  DWORD dwFileSizeLo = GetFileSize(hFile, &dwFileSizeHi);

  if( dwFileSizeLo == 0 && dwFileSizeHi == 0 )
  {
     _tprintf(TEXT("Cannot map a file with a length of zero.\n"));
     return FALSE;
  }

  // Create a file mapping object.
  hFileMap = CreateFileMapping(hFile,
                    NULL,
                    PAGE_READONLY,
                    0,
                    1,
                    NULL);

  if (hFileMap)
  {
    // Create a file mapping to get the file name.
    void* pMem = MapViewOfFile(hFileMap, FILE_MAP_READ, 0, 0, 1);

    if (pMem)
    {
      if (GetMappedFileNameA (GetCurrentProcess(),
                             pMem,
                             pszFilename,
                             MAX_PATH))
      {

        // Translate path with device name to drive letters.
        TCHAR szTemp[BUFSIZE];
        szTemp[0] = '\0';

        if (GetLogicalDriveStrings(BUFSIZE-1, szTemp))
        {
          TCHAR szName[MAX_PATH];
          TCHAR szDrive[3] = TEXT(" :");
          BOOL bFound = FALSE;
          TCHAR* p = szTemp;

          do
          {
            // Copy the drive letter to the template string
            *szDrive = *p;

            // Look up each device name
            if (QueryDosDevice(szDrive, szName, MAX_PATH))
            {
              size_t uNameLen = _tcslen(szName);

              if (uNameLen < MAX_PATH)
              {
                bFound = _tcsnicmp(pszFilename, szName, uNameLen) == 0
                         && *(pszFilename + uNameLen) == _T('\\');

                if (bFound)
                {
                  // Reconstruct pszFilename using szTempFile
                  // Replace device path with DOS path
                  TCHAR szTempFile[MAX_PATH];
                  sprintf(szTempFile,
                            TEXT("%s%s"),
                            szDrive,
                            pszFilename+uNameLen);
                  strcpy(pszFilename, szTempFile);
                }
              }
            }

            // Go to the next NULL character.
            while (*p++);
          } while (!bFound && *p); // end of string
        }
      }
      bSuccess = TRUE;
      UnmapViewOfFile(pMem);
    }

    CloseHandle(hFileMap);
  }
  _tprintf(TEXT("File name is %s\n"), pszFilename);
  return(bSuccess);
}

int _tmain(int argc, TCHAR *argv[])
{
    FILE *f;
    HANDLE hFile;

    if( argc != 2 )
    {
        _tprintf(TEXT("This sample takes a file name as a parameter.\n"));
        return 0;
    }
    f=fopen(argv[1],"r");
    if (NULL==f) return 0;
    hFile=(HANDLE)_get_osfhandle(fileno(f));
//  hFile = CreateFile(argv[1], GENERIC_READ, FILE_SHARE_READ, NULL,
//      OPEN_EXISTING, 0, NULL);

    if(hFile == INVALID_HANDLE_VALUE)
    {
        _tprintf(TEXT("CreateFile failed with %d\n"), GetLastError());
        return 0;
    }
    GetFileNameFromHandle( hFile );
    fclose(f);
    return 0;
}
//C:\test>test c:\windows\system32\kernel32.dll
//File name is C:\WINDOWS\system32\kernel32.dll
//
Sodino 2015-03-06
  • 打赏
  • 举报
回复
引用 3 楼 ri_aje 的回复:
FILE 就管文件,不管路径名。
额..看了下java.io.File.java,路径名是java层面的数据管理了.... 那想追问,为何FILE->_p会是NULL呢?
ri_aje 2015-03-06
  • 打赏
  • 举报
回复
FILE 就管文件,不管路径名。
Sodino 2015-03-05
  • 打赏
  • 举报
回复
引用 1 楼 hanyue03 的回复:
 FILE * tmp = fopen(str, "ra");//str不就是文件名(路径)吗?FILE 只是个句柄[标识 _p 注释里面写的很清楚
嗯 但这个str可能只是个相对路径名称,想着fopen()以后,可不可能拿得到绝对路径? 另:奇怪为什么 FILE->_p为什么会是null呢?
hanyue03 2015-03-05
  • 打赏
  • 举报
回复
 FILE * tmp = fopen(str, "ra");//str不就是文件名(路径)吗?FILE 只是个句柄[标识 _p 注释里面写的很清楚

33,311

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 新手乐园
社区管理员
  • 新手乐园社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧