12.2 IO(2)

这篇继续说一下IO中常见的函数以及标准IO的机理。
内容在书13.4,13.5,13.6章。

1 文件IO函数

上一篇介绍的函数都类似于文件IO函数。主要区别在于文件IO需要用FILE*指定待处理的文件。
而接下来介绍的函数则使用 指向FILE的指针(如stdout)指定一个文件。

1.1 fprintf_s()与fscanf_s()

这两个函数的工作方式与printf()和scanf()类似,区别在于这两个函数的第一个参数需要指定待处理的文件

1.1.1 将键盘输入的文字记录至磁盘并从磁盘中读出再输出
//将键盘输入内容写入到磁盘再读取并输出
#include <stdio.h>
#include <string.h>

#define LENGTH 128

int main(void)
{
	char out[] = "J:\\IO_Write\\keyboard.txt";
	show_write_keyboard_input(out);
	return 0;
}

int show_write_keyboard_input(char* path)
{
	FILE* out;
	char file_name[LENGTH];
	char string[LENGTH];
	printf("请在看到这一行字之后开始输入文字,若输入#则代表结束输入。\n");
	strncpy_s(file_name, LENGTH - 8, path, LENGTH - 8);
	file_name[LENGTH - 8] = '\0';
	fopen_s(&out, file_name, "a+");//a+:追加模式
	while ((fscanf_s(stdin, "%s", string, 120) == 1) && string[0] != '#')//第一个字符为#则中断输入
	{
		fprintf_s(out, "%s", string);
	}
	rewind(out);//指针返回文件开始处
	printf_s("现在开始输出刚才从键盘输入的内容:\n");
	while (fscanf_s(out, "%s", string, 120) == 1)
	{
		fprintf_s(stdout, "%s\n", string);
	}

	return 0;
}

运行结果

请在看到这一行字之后开始输入文字,若输入#则代表结束输入。
g4f1g1f1g1f1f1
fdsdgd544651
411fdsggffsg#46465
#
现在开始输出刚才从键盘输入的内容:
g4f1g1f1g1f1f1fdsdgd544651411fdsggffsg#46465

1.2 fgets()与fputs()

下面的表格简单的对比了这两个函数。

函数参数返回值
fgets()char*,待输入字符串大小(int), FILE*char*
fputs()char*, FILE*int

fgets()将会读取输入直到第一个换行符的后面,或文件结尾,或STRLEN-1个字符。随后会在字符串末尾添加一个空字符表示这是一个字符串。在读取到EOF时会返回NULL

**fputs()**与puts()的不同在于,fputs()在输出字符串时不会在末尾为其添加换行符。

2 随机访问

2.1 fseek()与ftell()

fseek()可以将文件看成一个数组,在fopen()打开的文件中移动到任意字节处。
ftell() 则是用于得到文件位置指针当前位置相对于**文件首的偏移**字节数

2.1.1 倒序输出文件的内容
#include <string.h>
#define LENGTH 128

int main(void)
{
	//文件内容是26个字母小写a-z,大写A-Z,数字1234567890
	char path[] = "J:\\IO_Write\\random.txt";
	random_read_input(path);
	return 0;
}

int random_read_input(char* path)
{
	FILE* in;
	char input[LENGTH];
	char c;
	long count, last;
	strncpy_s(&input, LENGTH - 8, path, LENGTH - 8);
	input[LENGTH - 8] = '\0';
	fopen_s(&in, input, "r");

	fseek(in, 0L, SEEK_END); //定位到文件末尾
	last = ftell(in);

	for ( count = 1L; count <= last; count++)
	{
		fseek(in, -count, SEEK_END); //从最后往最前面读取
		c = getc(in);
		putchar(c);
	}
	printf("\n");
	fclose(in); //关闭文件
	return 0;
}

运行结果

0987654321ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba
2.1.2 fseek()的工作原理

可以通过下面的表格对比一下这两个函数。

函数参数返回值
fseek()FILE*, 偏移量(long), 模式(int)int
ftell()FILE*long

对于fseek()中的偏移值,可以是证书,可以是负数,也可以是0,但是必须加上L转换为long类型。
第三个参数,则是确定起始点。下面是C语言预定义的常量。

模式偏移量起始点旧实现的替代值
SEEK_SET文件开始处0L
SEEK_CUR当前位置1L
SEEK_END文件结尾2L

看看下面的函数,想想代表了什么。

fseek(in, 10L, SEEK_SET); //定位至文件开始第10字节
fseek(in, -5L, SEEK_CUR); //定位至当前位置后第5字节
fseek(in, -15L, SEEK_END); //文件结尾处回退15字节

2.2 fgetpos()与fsetpos()

这两个函数主要是解决fseek()与ftell()的文件大小只有long范围的问题。
这两个函数用fpos_t代替了原来的long类型。

3 标准IO的机理

对于文件的IO,第一步操作一般都是使用fopen_s()打开文件,该函数同时还创建了一个缓冲区

第二步则是通过输入函数读取内容,可能是标准输入流,也可能是一个文件。一旦调用这些函数,文件的数据块就会被拷贝至缓冲区。缓冲区的大小在不同的实现中有不同的数值,一般都是512字节的倍数。最初调用时,除填充缓冲区之外,还需要设置FILE*指向结构的值。

初始化完成并已经将缓冲区所有字符读取完毕后,会将下一块缓冲区大小的数据读取至缓冲区,重复上面的操作直至将整个文件读取完毕。

输出函数操作与读取输入操作相反,当缓冲区被填满时,数据将会被拷贝至文件中

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
你出现 `IO 错误: NL Exception was generated` 错误的原因可能是你的Oracle JDBC驱动程序版本不支持使用 `javax.net.ssl.*` 参数来配置SSL连接。从Oracle JDBC驱动程序版本 12.2c 开始,JDBC驱动程序引入了新的参数来配置 SSL 连接。 如果你使用的是较旧版本的Oracle JDBC驱动程序,可以尝试使用以下方式来启用 SSL 连接: 1. 将 Oracle 的 `javax.net.ssl.*` 参数设置为系统属性: ``` System.setProperty("javax.net.ssl.trustStore", "/path/to/truststore"); System.setProperty("javax.net.ssl.trustStorePassword", "mypassword"); ``` 2. 在JDBC URL中添加以下参数: ``` jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS=(PROTOCOL=tcps)(HOST=myhost)(PORT=2484))(CONNECT_DATA=(SERVICE_NAME=myorcldbservicename))(SSL_VERSION=1.2)(SSL_CIPHER_SUITES=(SSL_RSA_WITH_AES_256_CBC_SHA256))) ``` 请注意,上述示例中的 `SSL_VERSION` 和 `SSL_CIPHER_SUITES` 参数可以根据你的 SSL 配置进行更改。 如果你使用的是 Oracle JDBC 驱动程序版本 12.2c 或更高版本,则可以使用以下方式来配置 SSL 连接: 1. 在JDBC URL中添加以下参数: ``` jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS=(PROTOCOL=tcps)(HOST=myhost)(PORT=2484))(CONNECT_DATA=(SERVICE_NAME=myorcldbservicename))(SECURITY=(SSL_SERVER_CERT_DN="CN=myservername"))) ``` 请注意,上述示例中的 `SSL_SERVER_CERT_DN` 参数应该设置为SSL服务器证书的 Distinguished Name (DN)。 2. 将 SSL 证书添加到 Java 信任库中: ``` keytool -import -alias myserver -file /path/to/server/certificate.pem -keystore /path/to/truststore ``` 请注意,需要将 `/path/to/server/certificate.pem` 替换为 SSL 服务器证书的路径和文件名,将 `/path/to/truststore` 替换为 Java 信任库的路径和文件名。在执行上述命令时,需要提供 Java 信任库的密码。 以上是两种配置 SSL 连接的方式,你可以根据自己的实际情况选择其中一种方式。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值