c++ - 如何使用 C/++ 在 linux 中正确写入磁带驱动器?
问题描述
我目前正在尝试通过 C++ 写入 LTO 磁带设备。我的问题是,随后的写入请求将导致“无效参数”错误,而第一次调用似乎工作得很好。
我已将磁带机设置为使用 64k 的固定块大小(这意味着一次只能以 64k 或 64k 倍数的块写入)。
现在尝试通过 fwrite() 对其进行写入时,第一次调用将成功(或至少返回写入的请求的条目数量),但后续调用(使用相同的参数)将导致没有数据被写入( fwrite 返回 0) 和“无效参数”错误。
以下是一个小的示例应用程序,用于复制该问题。
#include <iostream>
#include <unistd.h>
#define BLOCK_SIZE (64 * 1024)
#define DATA_BLOCKS 32
#define byte unsigned char
int main(int argc, char *argv[]) {
if (argc <= 1) {
std::cout << "Missing first parameter: Target file\n";
return 1;
}
// Create file handle to access tape device in RW mode
FILE* handle;
const char* targetFile = argv[1];
if (access(targetFile, R_OK | W_OK) == 0) {
handle = fopen(targetFile, "r+");
printf("Create handle OK: %s\n", targetFile);
} else {
printf("Could not access %s: Missing rad or write permission\n", targetFile);
return 1;
}
// Create an byte array with data for DATA_BLOCKS blocks
byte *data = new byte[BLOCK_SIZE * DATA_BLOCKS];
// Initialize with some data
for (int i = 0; i < BLOCK_SIZE * DATA_BLOCKS; i++) {
data[i] = '5';
}
// Write data in BLOCK_SIZE chunks, blocksToWrite times per fwrite() call, in numberOfWriteCalls fwrite() calls
size_t blocksToWrite = 4;
int numberOfWriteCalls = 5;
size_t written;
for (int i = 0; i < numberOfWriteCalls; i++) {
written = fwrite(data, BLOCK_SIZE, blocksToWrite, handle);
printf("Round %d: Wrote %d entries of expected %d entries\n", i+1, (int) written, (int) blocksToWrite);
// Check if there was an error and if so, print error info to stderr
if (ferror(handle)) {
printf("Error while writing:\n");
perror("");
clearerr(handle);
}
/* Start modification: Added flushing, as pointed out by user7860670 */
fflush(handle);
// Check if there was an error and if so, print error info to stderr
if (ferror(handle)) {
printf("Error while flushing:\n");
perror("");
clearerr(handle);
}
/* End modification: Added flushing, as pointed out by user7860670 */
}
delete[] data;
// Close file handle
fclose(handle);
return 0;
}
此代码调用 fwrite 函数 5 次,每次尝试写入 4 块 64k 数据。这适用于普通文件,但在我的所有磁带设备上返回以下输出:
Create handle OK: /dev/nst0
Round 1: Wrote 4 entries of expected 4 entries
Round 2: Wrote 0 entries of expected 4 entries
Invalid argument
Round 3: Wrote 0 entries of expected 4 entries
Invalid argument
Round 4: Wrote 0 entries of expected 4 entries
Invalid argument
Round 5: Wrote 0 entries of expected 4 entries
Invalid argument
可以看出,第一次调用的反应如预期:fwrite 返回已写入 4 块数据。但是所有后续调用,即使使用相同的参数,也会返回 0 个写入块和“无效参数”错误。
尝试写入我不知道的磁带文件时是否有任何“特殊调味料”,或者我可能以错误的方式使用 fwrite 功能?
解决方案
推荐阅读
- php - 如何使用 PHP SDK 从 AdmobMediation 获取中介报告
- excel - 如何从单个循环中提取多个项目并填充多个列
- python - Scrapy - 使用带有项目列表的“规范化空间”
- javascript - 浏览器在正常启动时是否可以在执行过程中变成无头,反之亦然?
- javascript - 在倒数计时器结束后设置秒表计时器
- node.js - 通过 React 表单中的节点进行 API 连接
- xml - 即时调用的 WSDL 链接中是否存在语法错误?如果 ref 存在 [...]
- python-3.x - 将科学记数法转换为日期时间
- java - 具有来自一对一映射实体的属性
- python - Python 请求 - 指定在 xml 响应中获得什么