- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我一直在尝试阅读 iostreams 并更好地理解它们。有时我发现它强调插入器( <<
)和提取器( >>
)旨在用于文本序列化。这是几个地方,但这篇文章是一个很好的例子:
http://spec.winprog.org/streams/
外<iostream>
在某些情况下,<< 和 >> 以类似流的方式使用,但不遵守任何文本约定。例如,当 Qt 的 QDataStream
使用时,它们会写入二进制编码的数据。 :
http://doc.qt.nokia.com/latest/qdatastream.html#details
在语言级别,<< 和 >> 运算符属于您的项目要重载(因此 QDataStream 所做的显然是可以接受的)。我的问题是对于那些使用 <iostream>
的人来说,这是否被认为是一种不好的做法。使用 << 和 >> 运算符来实现二进制编码和解码。 (例如)是否有任何期望,如果写入磁盘上的文件,该文件应该可以使用文本编辑器查看和编辑?
是否应该始终使用其他方法名称并基于 read()
和 write()
?或者应该将文本编码仅仅视为与标准库 iostream 集成的类可以选择忽略的默认行为?
更新 关于此的一个关键术语问题似乎是“格式化”与“未格式化”的 I/O 的区别(与术语“文本”与“二进制”相反)。我发现了这个问题:
writing binary data (std::string) to an std::ofstream?
它有来自@TomalakGeret'kal 的评论说:“无论如何,我不想将 << 用于二进制数据,因为我的大脑将其读取为“格式化输出”,这不是你在做什么。同样,它完全有效,但我不会像那样混淆我的大脑。”
该问题的公认答案说,只要您使用 ios::binary
就可以了.这似乎支持了辩论中“没有任何问题”的一面……但我仍然没有看到关于这个问题的任何权威来源。
最佳答案
其实运营商<<
和 >>
是位移运算符;将它们用于 I/O 严格来说已经是一种误用。然而,这种误用与运算符重载本身一样古老,而今天的 I/O 是它们最常见的用法,因此它们被广泛认为是 I/O 插入/提取运算符。我很确定如果没有 iostreams 的先例,没有人会使用这些运算符进行 I/O(尤其是在 C++11 中,它具有可变参数模板,解决了使用这些运算符为 iostreams 解决的主要问题,在一个更清洁的方式)。另一方面,从语言的角度来看,重载operator<<
和 operator>>
可以表示任何您希望他们表示的意思。
所以问题归结为这些运算符的可接受用途是什么。为此,我认为必须区分两种情况:第一,在 iostream 类上工作的新重载,第二,在其他类上工作的新重载,可能被设计为像 iostreams 一样工作。
让我们首先考虑 iostream 类上的新运算符。让我首先观察到 iostream 类都是关于格式化的(以及相反的过程,可以称为“解格式”;“词法分析”在这里不太合适,因为提取器不能确定类型,但只能尝试根据给定的类型解释数据)。负责原始数据的实际 I/O 的类是流缓冲。但是请注意,正确的二进制文件不是您只转储内部原始数据的文件。就像一个文本文件(实际上更是如此),一个二进制文件应该对它所包含的数据有一个明确指定的编码。特别是如果文件需要在不同的系统上读取。因此,格式化输出的概念对于二进制文件也非常有意义;只是格式不同(例如,为整数值写入预定数量的字节,最重要的字节在前)。
iostreams 本身是用于处理文本文件的类,也就是说,处理其内容被解释为数据的文本表示的文件。许多内置行为都为此进行了优化,如果在二进制文件上使用可能会导致问题。一个明显的例子是默认情况下在尝试任何输入之前跳过空格。对于二进制文件,这显然是错误的行为。此外,语言环境的使用对二进制文件没有意义(尽管有人可能会争辩说可能存在“二进制语言环境”,但我不认为为 iostream 定义的语言环境为此提供了合适的接口(interface))。因此我会说写二进制 operator<<
或 operator>>
对于 iostream 类将是错误的。
另一种情况是为二进制输入/输出定义一个单独的类(可能重用流缓冲层来执行实际的 I/O)。由于我们现在谈论的是不同的类,因此上面的论证不再适用。所以现在的问题是:应该operator<<
和 operator>>
在 I/O 上被视为“文本插入/提取操作符”或更一般地被视为“格式化数据插入/提取操作符”?标准类仅将它们用于文本,但是,根本没有用于二进制 I/O 插入/提取的标准类,因此标准用法无法区分两者。
我个人会说二进制插入/提取与文本插入/提取足够接近,这种用法是合理的。请注意,您还可以制作有意义的二进制 I/O 操纵器,例如bigendian
, littleendian
和 intwidth(n)
确定要输出的整数的格式。
除此之外,还可以将这些运算符用于不是真正 I/O 的事情(并且您甚至不会想到使用 streambuf 层),例如从容器中读取或插入到容器中。在我看来,这已经构成了对运营商的滥用,因为那里的数据没有转换成或转换成不同的格式。它只是存储在一个容器中。
关于c++ - 插入器和提取器读取/写入二进制数据与文本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8230786/
我之前让 dll 注入(inject)器变得简单,但我有 Windows 7,我用 C# 和 C++ 做了它,它工作得很好!但是现在当我在 Windows 8 中尝试相同的代码时,它似乎没有以正确的方
我正在尝试制作一个名为 core-splitter 的元素,该元素在 1.0 中已弃用,因为它在我们的项目中起着关键作用。 如果您不知道 core-splitter 的作用,我可以提供一个简短的描述。
我有几个不同的蜘蛛,想一次运行所有它们。基于 this和 this ,我可以在同一个进程中运行多个蜘蛛。但是,我不知道如何设计一个信号系统来在所有蜘蛛都完成后停止 react 器。 我试过了: cra
有没有办法在达到特定条件时停止扭曲 react 器。例如,如果一个变量被设置为某个值,那么 react 器应该停止吗? 最佳答案 理想情况下,您不会将变量设置为一个值并停止 react 器,而是调用
https://code.angularjs.org/1.0.0rc9/angular-1.0.0rc9.js 上面的链接定义了外部js文件,我不知道Angular-1.0.0rc9.js的注入(in
我正在尝试运行一个函数并将服务注入(inject)其中。我认为这可以使用 $injector 轻松完成.所以我尝试了以下(简化示例): angular.injector().invoke( [ "$q
在 google Guice 中,我可以使用函数 createInjector 创建基于多个模块的注入(inject)器。 因为我使用 GWT.create 在 GoogleGin 中实例化注入(in
我在 ASP.NET Core 1.1 解决方案中使用配置绑定(bind)。基本上,我在“ConfigureServices Startup”部分中有一些用于绑定(bind)的简单代码,如下所示: s
我在 Spring MVC 中设置 initBinder 时遇到一些问题。我有一个 ModelAttribute,它有一个有时会显示的字段。 public class Model { privat
我正在尝试通过jquery post发布knockoutjs View 模型 var $form = $('#barcodeTemplate form'); var data = ko.toJS(vm
如何为包含多态对象集合的复杂模型编写自定义模型绑定(bind)程序? 我有下一个模型结构: public class CustomAttributeValueViewModel { publi
您好,我正在尝试实现我在 this article 中找到的扩展方法对于简单的注入(inject)器,因为它不支持开箱即用的特定构造函数的注册。 根据这篇文章,我需要用一个假的委托(delegate)
你好,我想自动注册我的依赖项。 我现在拥有的是: public interface IRepository where T : class public interface IFolderReposi
我正在使用 Jasmine 测试一些 Angular.js 代码。为此,我需要一个 Angular 注入(inject)器: var injector = angular.injector(['ng'
我正在使用 Matlab 代码生成器。不可能包含代码风格指南。这就是为什么我正在寻找一个工具来“ reshape ”、重命名和重新格式化生成的代码,根据我的: 功能横幅约定 文件横幅约定 命名约定 等
这个问题在这里已经有了答案: Where and why do I have to put the "template" and "typename" keywords? (8 个答案) 关闭 8
我开发了一种工具,可以更改某些程序的外观。为此,我需要在某些进程中注入(inject)一个 dll。 现在我基本上使用这个 approach .问题通常是人们无法注入(inject) dll,因为他们
我想使用 swing、spring 和 hibernate 编写一个 java 应用程序。 我想使用数据绑定(bind)器用 bean 的值填充 gui,并且我还希望它反射(reflect) gui
我有这段代码,当两个蜘蛛完成后,程序仍在运行。 #!C:\Python27\python.exe from twisted.internet import reactor from scrapy.cr
要点是 Spring Batch (v2) 测试框架具有带有 @Autowired 注释的 JobLauncherTestUtils.setJob。我们的测试套件有多个 Job 类提供者。因为这个类不
我是一名优秀的程序员,十分优秀!