itext library Document.add(Element element) method returns true 并且在写入 PDF 文件时磁盘已满时不会抛出任何异常
itext library Document.add(Element element) method returns true and does not throw any exception when the disk gets full while writing PDF files
我正在使用 itext java 库将 PDF 文件生成到 windows 硬盘。
我使用的方法是
com.itextpdf.text.Document.add(Element element)
该方法被多线程调用(可配置)。
让我用下面的一些示例数字解释发生了什么:
例如,我必须编写 10 个 pdf 文件,每个文件大小为 100KB。所需的总大小为 1000KB。硬盘中可用的space为500KB。
发生了三件事:
- 当代码开始执行时,它最初会创建一些 100KB 的文件。假设创建了 2 个文件和 add() 方法 returns true,表示文件已成功创建(这是预期的行为)
- 然后它创建一些不完整的文件,大小为 50KB 或 60KB 或 40KB(一些数字小于实际大小)并抛出 IOException。在这种情况下,我将文档标记为 "incomplete",稍后当磁盘 space 可用时,我重写了该文件。那个时候旧文件被新文件覆盖,新文件是完美的。
- 现在,假设写入了 6 个文件,只剩下 4 个文件(也可能是 2 个或 3 个)。在这种情况下,将创建 2KB 或 0KB 或 4KB 的不完整文件,并且 add() 方法不会抛出任何异常并且 RETURNS "TRUE"(这意味着文件已成功写入)。这些文件已损坏。当磁盘 space 可用时我无法重写,因为我被告知它已成功写入。
所以问题出在第三种情况下。该方法在最后表现出错误。在第二种情况下,它会抛出异常,而在第三种情况下会抛出异常。
我的代码写入了数千个文件,并且在生产中为多个服务器配置了大量线程。
当有足够的磁盘 space 可用时,此代码可以完美运行,问题是磁盘 space 在写入文件时耗尽。
我使用的itext库版本是5.0.6。
有什么帮助吗?
OP 在评论中澄清:
My point is why add method returns true when the disk write is not done yet?
方法注释说:
/**
* Adds an <CODE>Element</CODE> to the <CODE>Document</CODE>.
*
* @param element
* the <CODE>Element</CODE> to add
* @return <CODE>true</CODE> if the element was added, <CODE>false
* </CODE> if not
* @throws DocumentException
* when a document isn't open yet, or has been closed
*/
因此根据文档,true
仅表示该元素已添加到此 Document
实例本身,而不是光盘上的某个文件。
正如您肯定知道的那样,iText Document
仅仅是一个文档抽象,注册的 DocListener
实例会监听,如果至少有一个监听器 returns true
对于 add
,Document.add
returns 为真。
A PdfWriter.getInstance
调用添加一个新的 PdfDocument
实例作为 Document
侦听器,并且 PdfDocument.add
returns true
只要关联writer 既没有 null
也没有暂停,并且要添加的元素属于已知类型,因此不会抛出异常。所以很可能它 returns true
一直在你的程序中。
顺便说一句:
The itext library version I am using is 5.0.6
那个版本很旧,所以除非你有一个非常特殊的支持合同,否则你可能不会得到一个二进制兼容的库版本,它的行为符合你的预期。
我正在使用 itext java 库将 PDF 文件生成到 windows 硬盘。 我使用的方法是
com.itextpdf.text.Document.add(Element element)
该方法被多线程调用(可配置)。 让我用下面的一些示例数字解释发生了什么: 例如,我必须编写 10 个 pdf 文件,每个文件大小为 100KB。所需的总大小为 1000KB。硬盘中可用的space为500KB。 发生了三件事:
- 当代码开始执行时,它最初会创建一些 100KB 的文件。假设创建了 2 个文件和 add() 方法 returns true,表示文件已成功创建(这是预期的行为)
- 然后它创建一些不完整的文件,大小为 50KB 或 60KB 或 40KB(一些数字小于实际大小)并抛出 IOException。在这种情况下,我将文档标记为 "incomplete",稍后当磁盘 space 可用时,我重写了该文件。那个时候旧文件被新文件覆盖,新文件是完美的。
- 现在,假设写入了 6 个文件,只剩下 4 个文件(也可能是 2 个或 3 个)。在这种情况下,将创建 2KB 或 0KB 或 4KB 的不完整文件,并且 add() 方法不会抛出任何异常并且 RETURNS "TRUE"(这意味着文件已成功写入)。这些文件已损坏。当磁盘 space 可用时我无法重写,因为我被告知它已成功写入。
所以问题出在第三种情况下。该方法在最后表现出错误。在第二种情况下,它会抛出异常,而在第三种情况下会抛出异常。 我的代码写入了数千个文件,并且在生产中为多个服务器配置了大量线程。
当有足够的磁盘 space 可用时,此代码可以完美运行,问题是磁盘 space 在写入文件时耗尽。
我使用的itext库版本是5.0.6。 有什么帮助吗?
OP 在评论中澄清:
My point is why add method returns true when the disk write is not done yet?
方法注释说:
/**
* Adds an <CODE>Element</CODE> to the <CODE>Document</CODE>.
*
* @param element
* the <CODE>Element</CODE> to add
* @return <CODE>true</CODE> if the element was added, <CODE>false
* </CODE> if not
* @throws DocumentException
* when a document isn't open yet, or has been closed
*/
因此根据文档,true
仅表示该元素已添加到此 Document
实例本身,而不是光盘上的某个文件。
正如您肯定知道的那样,iText Document
仅仅是一个文档抽象,注册的 DocListener
实例会监听,如果至少有一个监听器 returns true
对于 add
,Document.add
returns 为真。
A PdfWriter.getInstance
调用添加一个新的 PdfDocument
实例作为 Document
侦听器,并且 PdfDocument.add
returns true
只要关联writer 既没有 null
也没有暂停,并且要添加的元素属于已知类型,因此不会抛出异常。所以很可能它 returns true
一直在你的程序中。
顺便说一句:
The itext library version I am using is 5.0.6
那个版本很旧,所以除非你有一个非常特殊的支持合同,否则你可能不会得到一个二进制兼容的库版本,它的行为符合你的预期。