Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/329.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 关于文件I/O(读/写消息字符串)的许多问题_C_File Io_Fread_Fwrite - Fatal编程技术网

C 关于文件I/O(读/写消息字符串)的许多问题

C 关于文件I/O(读/写消息字符串)的许多问题,c,file-io,fread,fwrite,C,File Io,Fread,Fwrite,对于我正在做的这个大学项目(我在过去发表过几篇文章),这是一种社交网络,它需要用户交换消息的能力 首先,我将数据结构设计为在一个链表中保存所有消息,将消息大小限制为256个字符。然而,我想我的导师会更喜欢我把这些信息保存在磁盘上,并且只在我需要的时候阅读它们。当然,他们不会说他们喜欢什么,我需要做出选择,尽我所能证明我为什么选择了那条路线 需要记住的一件事是,我只需要保存每个用户最新的20条消息,不再需要了 现在我有一个作为收件箱的哈希表,它将在用户配置文件中。此哈希表将按名称(发送消息的用户)

对于我正在做的这个大学项目(我在过去发表过几篇文章),这是一种社交网络,它需要用户交换消息的能力

首先,我将数据结构设计为在一个链表中保存所有消息,将消息大小限制为256个字符。然而,我想我的导师会更喜欢我把这些信息保存在磁盘上,并且只在我需要的时候阅读它们。当然,他们不会说他们喜欢什么,我需要做出选择,尽我所能证明我为什么选择了那条路线

需要记住的一件事是,我只需要保存每个用户最新的20条消息,不再需要了

现在我有一个作为收件箱的哈希表,它将在用户配置文件中。此哈希表将按名称(发送消息的用户)编制索引。每个元素的值将是一个数据结构,其中包含一个包含20个元素的
size\t
数组(如上所述的20条消息)。其思想是跟踪磁盘文件偏移量和写入的字节数。然后,当我需要读取消息时,我只需要使用
fseek()
并读取必要的字节

我认为这可以很好地工作。。。我可以只使用一个文件来保存来自网络中所有用户的所有消息。我之所以说一个文件,是因为一位同事问一位讲师如何独立保存每个用户的消息,他回答说这可能不是最好的方法,因为文件系统有它的局限性。这就是为什么我想走单文件路线

然而,这带来了一个问题。。。因为我只需要保存最近的20条消息,所以当我达到此限制时,我需要丢弃旧的消息

我不知道怎么做。。。我只知道
fread()
fwrite()
从文件读取/写入字节。我如何才能转到文件偏移量并说“嘿,删除以下X字节”?即使我能做到,还有另一个问题。。。低于该值的所有偏移量都将完全不同,我必须处理所有用户邮箱以修复该问题。这将是一种痛苦


那么,有什么建议可以解决我的问题吗?你有什么建议?

你不能随意删除文件中间的字节;唯一有效的方法是重写整个文件而不使用它们。不管这样做是否是一个好主意,如果您有固定长度的字段,一个解决方案就是用最新的消息覆盖最旧的消息;这样,磁盘上消息的大小/位置不会改变,因此其他偏移量都不会受到影响


编辑:如果允许您使用外部库,那么制作一个简单的数据库可能是一个很好的解决方案

你的生活方式比你所需要的要复杂得多

如果您的邮件为256个字符,则使用256个字符的数组保存每条邮件

使用fwrite将其写入磁盘,使用fread读取,通过将字符串的第一个字符更改为\0(或您喜欢的任何其他字符)将其删除,然后将其写入磁盘


以简单的结构(username/recno)保存消息索引,并使用fseek在文件中跳转。您可以在写入新记录时强制执行下一个可用记录(从文件开头开始读取,在点击\0时停止),也可以在数组中保留可用记录的索引,并在写入新记录时获取其中一个(或者如果数组为空,则查看文件结尾并写入完整的新记录)

为了完整性,我想建议另一种解决方案:

字符串应以空字节字符结尾,
“hello world\0”
,因此您可以读取原始二进制数据,直到到达
“\0”
。 其他数据类型有固定位,注意字节顺序(endian)

您还可以在每条消息之前定义有效负载,以便了解其字符串长度:

"11hello world;2hi;15my name is loco"

因此,可以将原始代码片段视为数据字段。

我没有得到您的大部分答案,我认为您没有正确理解这个问题。我可以说的一件事是,我不想使用256个字符的数组,我不想将消息存储在内存中。这是我的第一个方法,这是我试图避免的。这不仅仅是一个用户的一条消息,而是数千个用户的20条消息(当然最多)。您必须将活动消息放在某个位置,以便放入256字符数组。将阵列保存到磁盘作为一条256字符的记录,即使消息长度只有10个字符。然后,您可以通过查看recno*256轻松找到它。在一个简单的结构中跟踪recno和sender,如果您愿意,可以在ram或其他磁盘文件中保存一个数组。我看不出有什么不清楚的地方。具有固定长度字符串和单独索引数组的简单随机访问文件。就像我说的,我不喜欢/不想要那个。我不打算为每条消息保存256个字节,因为它应该只保存几个字节(如果消息确实很小的话)。这是对空间的浪费。这可能是对空间的浪费,但它使事情变得简单得多。如果要分配大小可变的记录,则必须跟踪当前所有可用空间块及其大小,包括在有两个相邻可用块时合并它们。这果汁似乎不值得挤。我就是这么想的。。。我不喜欢使用固定长度的消息。最大值为256,但如果消息是简单的“嗨,你好吗?”,我不想写入256字节。我可以使用这样的外部lib。那会破坏目的。。。