Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ros2 bag play error on windows foxy - [rosbag2_transport]: Failed to play: cannot get file size #175

Open
karthiknit1 opened this issue Mar 7, 2023 · 2 comments
Labels

Comments

@karthiknit1
Copy link

karthiknit1 commented Mar 7, 2023

when there is only rosbag2_2021_09_27-09_11_59.db3 file and no metadata.yaml file, when I tried to play the bag file using the command "ros2 bag play rosbag2_2021_09_27-09_11_59.db3", the following error is encountered in ROS 2 Foxy terminal on windows.

[ERROR] [1652675142.815790900] [rosbag2_transport]: Failed to play: cannot get file size: The file pointer cannot be set on the specified device or file.

As per the discussion here, this is an issue in rcpputils package - ros2/rosbag2#1019.

This issue is seen happening only with larger bag files.

Expected Behavior
Bag file should be played successfully.

Actual Behavior
ros2 bag play rosbag2_2021_09_27-09_11_59.db3
ros2 bag info rosbag2_2021_09_27-09_11_59.db3
Both the above commands are leading to the below error on windows only:
[ERROR] [1652675142.815790900] [rosbag2_transport]: Failed to play: cannot get file size: The file pointer cannot be set on the specified device or file.

To Reproduce
** Steps to reproduce the behavior, e.g.

record a bag file.(around 8GB) in ROS 2 Foxy terminal.
play the bag using "ros2 bag play bagFileName". Here instead of bag folder, provide bag file name(.db3)
System (please complete the following information)
OS: Windows
ROS 2 Distro: Foxy
Version: Installed binary of latest Foxy

@karthiknit1
Copy link
Author

karthiknit1 commented Mar 27, 2023

@clalancette This is a problem in underlying implementation of the rcpputils::fs::path::file_size() from ros2/rcpputils/src/filesystem_helper.cpp in particularly for Windows platform. I was able to get this issue fixed with the following change:

uint64_t path::file_size() const
{
  if (this->is_directory()) {
    auto ec = std::make_error_code(std::errc::is_a_directory);
    throw std::system_error{ec, "cannot get file size"};
  }

#ifdef _WIN32
  // On Windows "stat" the struct stat returned by the stat function has a 32-bit size field (st_size)
  // which can't handle file sizes larger than 2GB. To handle large files on Windows, use the
  // _stati64 function instead of stat.
  struct _stati64 stat_buffer;
  const auto rc = _stati64(path_.c_str(), &stat_buffer);

  if (rc != 0) {
    std::error_code ec{errno, std::system_category()};
    errno = 0;
    throw std::system_error{ec, "cannot get file size"};
  } else {
    return static_cast<uint64_t>(stat_buffer.st_size);
  }
#else
  struct stat stat_buffer;
  const auto rc = stat(path_.c_str(), &stat_buffer);

  if (rc != 0) {
    std::error_code ec{errno, std::system_category()};
    errno = 0;
    throw std::system_error{ec, "cannot get file size"};
  } else {
    return static_cast<uint64_t>(stat_buffer.st_size);
  }
#endif
}

This change is applicable in following functions in ros2/rcpputils/src/filesystem_helper.cpp:
path::is_directory(), path::is_regular_file()
This change is also applicable in following functions in ros2/rcutils/src/filesystem.c:
rcutils_is_directory(), rcutils_is_file(), rcutils_exists(), rcutils_is_readable(), rcutils_is_writable(), rcutils_is_readable_and_writable(), rcutils_get_file_size().

Could you review the above change and see if we can create a pull request with this fix.

Thanks,
Karthik Reddy

@mjcarroll
Copy link
Member

Thanks for debugging this. I think if you could add a test and a pull request in rcutils, we can continue the conversation there.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants