2017-12-10 20 views
1

ファイルの先頭から32ビットの符号なしオフセットを持つファイル形式(TIFF)を読み込んでいます。32ビット符号なしオフセットをfseek

は残念ながらfseek関数のプロトタイプは、私は特定のオフセットのファイルに行くと通常の方法は、次のとおりですので、オフセット

int fseek (FILE * stream, long int offset, int origin); 

が署名されています。このような状況にどう対処すればよいですか?私はシークのために別の機能を使用すべきですか?

+0

あなたはどのOSですか? 32ビットアーキテクチャを使用していますか? – melpomene

+0

@melpomeneコードは、32ビットと64ビットの両方のアーキテクチャで動作する必要があり、異なるマシンやオペレーティングシステムで実行できます。 –

+0

2または4GBを超えるTIFFファイルは珍しいことではありません。あなたのCRTには長い議論が必要な選択肢があります。あなたはそのドキュメントを見なければなりません。 –

答えて

0

あなたはこの関数はのlseek関数に似てThe GNU C lib - Setting the File Position of a Descriptor

から

int fd = fileno (stream); 

リアクションlseek64()man page

#define _LARGEFILE64_SOURCE  /* See feature_test_macros(7) */ 
    #include <sys/types.h> 
    #include <unistd.h> 

    off64_t lseek64(int fd, off64_t offset, int whence); 

を使用しようとすることができます。相違点は、offsetパラメータがoff_tの代わりにoff64_t型であり、32ビットマシンで2^31バイトより大きく2^63バイトまでのファイルをアドレス可能にする点です。ファイル記述子filedesは、open64を使用して開く必要があります。そうしないと、off64_tで可能な大きなオフセットは、小さなファイルモードの記述子でエラーにつながります。

32ビットマシンでソースファイルが_FILE_OFFSET_BITS == 64でコンパイルされている場合、この関数は実際にはlseekという名前で使用できるため、32ビットインタフェースを透過的に置き換えます。 Streams and File Descriptorsストリームはファイルディスクリプタの面で実装されているので

から約fdstream

は、あなたは、ストリームからファイル記述子を抽出し、ファイルディスクリプタに直接低レベルの操作を行うことができます。また、最初に接続をファイルディスクリプタとして開き、そのファイルディスクリプタにストリームを関連付けることもできます。

+1

'fseeko'の代わりに' fseeko'が適切ではないでしょうか? 'lseek64'は' FILE * 'では動作しません。 – melpomene

+0

'lseek64'は' fd'を使いますが、答えの先頭近くに 'FILE * '、' int fd = fileno(stream); '([fileno]( –

+1

'FILE'の根底にあるファイル記述子を使いこなすことは、stdioと混同してデータを破壊する良い方法のように聞こえます。 – melpomene

0

この質問をより深く検討し、他のコメントと回答(ありがとう)を考慮した後、最も簡単なアプローチは、オフセットが2147483647バイトより大きい場合、2つのシークを行うことです。これにより、オフセットをuint32_tのままにして、fseekを使用し続けることができます。位置コードは、このようなことである。

// note: error handling code omitted 
uint32_t offset = ... (whatever it is) 
if(offset > 2147483647){ 
    fseek(file, 2147483647, SEEK_SET); 
    fseek(file, (long int)(offset - 2147483647), SEEK_CUR); 
} else { 
    fseek(file, (long int) offset, SEEK_SET); 
} 

64ビットタイプを使用しての問題点は、コードは、(とりわけ)32ビットアーキテクチャ上で実行されるかもしれないということです。構造fpos_tを使用して任意に大きなオフセットを管理する関数fsetposがありますが、それは複雑さの範囲をもたらします。 fsetposは、私が本当に大きなサイズのオフセットを本当に使用していれば意味があるかもしれませんが、可能な限り大きなオフセットがuint32_tであることを知っているので、ダブルシークはその必要性を満たしています。

この解決策では、すべてのTIFFファイルを32ビットシステムで処理できることに注意してください。 PixInsightのような商用プログラムを考えるなら、これの利点は明らかです。 PixInsightは、32ビットシステムで動作する場合、2147483648バイトより小さいTIFFファイルしか処理できません。フルサイズのTIFFファイルを処理するには、64ビットコンピュータで64ビット版のPixInsightを使用する必要があります。これはおそらく、PixInsightプログラマが内部的にオフセットを処理するために64ビットタイプを使用したためです。私のソリューションは32ビットタイプのみを使用しているので、32ビットシステムでフルサイズのTIFFファイルを扱うことができます(基本的なオペレーティングシステムがそのファイルを大量に処理できる限り)。

関連する問題