• ベストアンサー

大容量のファイルをseek関数で操作したい。

教えててください。 OSは、Turbo Linuxです。 現在、大容量のファイルを操作するのに、標準関数で行おうと思っています。 seek関数を使用する場合、先頭からの位置を指定しようとするとint型の位置(符号付4バイト)になるので、容量とすると、1.9GBが限界になると思います。 しかし、扱いたいファイルの容量は、もっと大容量(200GB以上)になるので、「シークできないのでは?」と思いました。 大容量のファイルを扱う方法は、標準関数以外に何かあるのでしょうか?それとも、駆使して操作するのでしょうか?

質問者が選んだベストアンサー

  • ベストアンサー
  • tatsu99
  • ベストアンサー率52% (391/751)
回答No.2

fseek関数を使用した場合、seek位置はlong int型で指定しますが、64ビットモードの場合、long intが8バイトの整数となります。従って、200G以上のサイズが扱えるはずです。 64ビットモードでfseekを使用する条件として 1.64ビットモードでコンパイルできるgccであること。(最近のgccはできるはずです。64ビット指定のオプションは調べてませんので、判りません) 2.カーネルが64ビットモードに対応していること (これも、対応しているLINUXがあるはずですが、詳細について調べたことはないので自信なし) が必要ですが、最近のLINUXであれば問題ないと思います。(自信なし)

その他の回答 (1)

  • liar_adan
  • ベストアンサー率48% (730/1515)
回答No.1

fsetpos()とfgetpos()という標準関数があります。(stdio.h内) fseek()、ftell()に概念的には同じですが、 ファイルの位置を表すのに、 long intの値ではなくてfpos_tという型を使っています。 使い方は別の資料で調べてください。 これを使えばなんとかなる可能性があります。 ヘッダファイルの中のfpos_tの型を調べて、 longより大きい型(新しくできたlong long intなど)か、 構造体だったら、1.9GB以上に対応しているかもしれません。 ただ、できない可能性もあります。 Linuxの実装については詳しくないので、できなかったらすみません。

関連するQ&A

  • perl seek関数について

    seek関数について少し質問させてください。 seek ファイルハンドル,オフセット,基準位置 と、某書籍に書いてありましたが、 オフセットのほうが元の位置で、基準位置が ファイルポインタを移動させる場所なんでしょうか? 例えば、 seek LOCK,0,2 の場合、ファイルハンドルLOCKの中のファイルポインタを0(ファイルの先頭)から2(ファイルの最後)に移動させるということでしょうか? そうであるならば、 seek LOCK,0,0 の場合、どういう意味になるのでしょう? 要点をまとめますと、ファイルハンドル以後の二つの数値の関係が今ひとつつかめていないということになります。 宜しくお願い致します。

    • ベストアンサー
    • CGI
  • VB.NETでファイル操作

    ファイルをオープンしたまま、ファイル内のデータを何度も読み込みたいのですが、Seekで読み込み位置を先頭にし、Peekでループさせ、一度全部読み込み終わった後、Seek文で先頭に戻し、再度ファイルの先頭から読み込ませようと思ったのですができません。 なぜなのでしょうか? // ファイルオープン StreamReader sr = new StreamReader( (System.IO.Stream) File.OpenRead("C:\\Temp\\Test.txt"), System.Text.Encoding.ASCII); // 最後まで読み出す sr.BaseStream.Seek(0, SeekOrigin.Begin); while (sr.Peek() > -1) { Console.WriteLine(sr.ReadLine()); } // もう一度 sr.BaseStream.Seek(0, SeekOrigin.Begin); while (sr.Peek() > -1) {         ←このWhileの中に入らない。 Console.WriteLine(sr.ReadLine()); } // ファイルクローズ sr.Close();

  • 大容量のファイルを送るための簡単迅速なストレージサイトは?

    大容量のファイルをEメールにて送りたいのですが、全部で1GBくらいになり、無料のおくりん坊やデータ便を駆使して何度も送っています。 しかしこの2つのサイトは、アップデートに非常に時間がかかり、一気に送れないので非常に面倒です。 少し有料でもよいので、もっとたくさんの容量を速めにアップロードができて簡単に送れるサイトがあれば教えてください。 ファイルバンクというのを見つけたんですが、無料なのでアップロードが遅いかも。。。と思ってしまいます。

  • ファイルサイズの取得について

    2つのテキストファイルのサイズを取得し、そのファイルサイズ分だけを動的にメモリを確保しようとしています。 int *c,*a;と宣言し、 fp=fopen("./data/Problem.txt","r");//1つ目のファイル fseek(fp, 0, SEEK_END); /* ファイルの終端までシーク */ size = ftell(fp); /* 終端の位置、すなわちファイルサイズを得る */ fseek(fp, 0, SEEK_SET); /* ファイルの先頭に戻る */ c = (int *)malloc(size); /* ファイルサイズ分メモリ確保 */ while((x=fgetc(fp))!=EOF){ c[i]=x; i++; } c[i]='\0'; i=0; fclose(fp); fpa=fopen("./data/Answer.txt","r");//2つ目のファイル fseek(fpa, 0, SEEK_END); size = ftell(fpa); fseek(fpa, 0, SEEK_SET); a = (int *)malloc(size); while((x=fgetc(fpa))!=EOF){ a[n]=x; n++; } a[n]='\0';//・・・・(1) n=0; fclose(fpa); とすると1つ目のファイルの方だけはうまくいくのですが、(1)の部分で 「sample.exeの0x00411dcでハンドルされていない例外が発生しました:0xc0000005:場所0x0000000に書き込み中にアクセス違反が発生しました。。」 というエラーが出ます。 また、 int *c,*a;を int *c,a[300]; のように片方を配列として宣言し、 //a = (int *)malloc(size); /* ファイルサイズ分メモリ確保 */ のようにコメントアウトすると上記のエラーは出ずにcにメモリは確保されているようです。 これは何故なのでしょうか? また、どうすればaとcでメモリを確保出来るようになるのでしょうか? よろしくお願いいたします。

  • Win SFU (Services for Unix)環境下で2GB超ファイルの末尾を取得したい

    業務上、2GB超のファイルを操作する必要があり、Win2Kを使って、その下でUnixコマンドを使用できるよう、SFU (Services for Unix) を使用しています。 そのシステム上で、2GB超のファイルの末尾nバイトを取得する処理が必要になるのですが、tail -c や、dd 等を使用しても、ファイルの末尾を取得するのではなく、変な動きをしてしまいます。 何か別の方法をご存知でしたら教えて頂けますでしょうか。 <前提> 1. ファイルの大きさは、都度変わりうる(min: 0, max: 数十GB) 2. NTFS上に、2GB超のファイルを既に書けていて、wc などの、単純にファイルを先頭から操作するコマンドは機能している。 3. SFUのkshを使用している。(他処理と連携したシステムの一部として作りたいので、パイプ・リダイレクト等で繋いで手操作はゼロにしたい) <既に試してダメだった方法> tail -c n ... 先頭からファイルを参照しているような動きをする tail +c ファイルサイズ-n ... 'Could not seek to byte -2139091255n file 'とエラーになる dd ... seek=n ... tail + と同様に、seekが失敗したとのエラー表示をし、エラーになる Perlでseekシステムコール システムコールが失敗する。 よろしくお願いします。

  • ファイル操作

    あるファイルから長さの違った数字や文字を読み込んで配列に格納したいのですが数字などの長さが違うとなんかおかしくなってしまいます; 例えば 1 a 1 2 a 2 3 b 3 4 b 4 などのファイルはできるのですが 0 1 2 3 a 3 4 b 4 5 c 5 の場合5つの配列に格納したいのです。1行目で1つ2行目で1つ3行目の 左、真ん中、右の数字でそれぞれ1つづつ格納したいのです。 それで自分でやったのですが typedef struct path{ int left [100]; int right[100]; char center [100]; }Path; int main(int argc,char *argv[]) { FILE *fp; Path path; int i=0; int first; int second[100]; fp = fopen(argv[1],"r"); while(fscanf(fp,"%d %c %d",&path.left[i],&path.center[i],&path.right[i])==3){ i++; } fclose(fp); このようにやると3行目からはきちんとよみこむのですが1、2行目がうまくできません@@; firstとsecondのそれぞれ1、2行目を入れたいのです。 fscanfをもう1つ増やすしてもやってみましたがうまくいきませんでした。 ちなみにfscanf関数のところをならったばかりです。 fgetcとかそのようなのを使うのでしょうか?(よくわからないですけど) よろしくお願いします。ちなみにLinuxでgcc、C言語です。

  • 標準出力上でのファイルポインタの扱いで困っています。

    標準出力上でのファイルポインタの扱いで困っています。 簡単な例で説明すると、 下のプログラムはファイル内で、一秒ごとに左から順に1を0で置き換えていくもので正常に動作します。 open(F, '+< temp'); print F "11111111111111111111111111111111\n"; for(0..31){ seek(F, $_, 0); print F '0'; sleep(1); } close(F); 同様のことが標準出力でも可能かと思って以下のようにしてみたのですが、うまくいきません。 open(STDOUT, '+<'); print STDOUT "11111111111111111111111111111111\n"; for (0..31){ seek(STDOUT, $_, 0); print STDOUT '0'; sleep(1); } close(STDOUT); } 2つ目の例では動作を見るかぎり、ファイルポインタは1111.....の先頭からのオフセットではなく、その次の行(空行)の先頭からのオフセットとなっているように見えます。つまり古い行には戻れていないようです。 Seek()は標準出力上では使えないのでしょうか?

    • ベストアンサー
    • Perl
  • 【WMV】大容量ファイルの再生【80GB】

    VLC,PotPlayer,WMPを試しましたが、再生はしますがシーク動かせません。 AdobeMediaEncoderで分割を試みましたが、読み込みません。 せめて分割等して、容量を減らせれば読み込むのでは?と考えます。 その他何でもいいので、アイデアください。 動画情報:Logicoolのムービー撮影(監視カメラとして24時間録画) .wmvファイル 約80GB

  • ファイルメーカー関数 Positionについて

    先日こちらのカテゴリーで質問させていただいた者です。 http://oshiete1.goo.ne.jp/qa5515143.html ご回答をいただいたのですが、解答のPosition関数を今まで 使用したことがなく、ファイルメーカーのヘルプを見たのですが Position ( テキスト ; 検索テキスト ; 先頭文字位置 ; 回数 ) 先頭文字位置 - テキスト文字列の先頭から検索開始位置までの文字数を示す数値式または数値を含むフィールド の意味が私の頭ではいまいち理解できず先に進めない状態です。 Position ( "Mississippi" ; "iss" ; 3 ; 1 )=5 どうして答えが5なのか疑問です。 柔らかく教えていただける方よろしくお願いします。

  • エンキューとデキューの操作関数

    エンキューとデキューの操作関数なのですが、 どのような考え方なのかがいまいちわからず困っています。 どなたか解説お願いします。 int QueueEnque(Queue *q, int x) { if(q->num >= q->max){ return (-1); }else{ q->num++; q->que[q->front++] = x; if(q->front == q->max){ q->front =0; } if(q->num ==1){ q->rear--; if(q->rear == -1){ q->rear = q->max-1; } } return (0); } } int QueueDeque(Queue *q, int *x) { if(q->num <= 0){ return (-1); }else{ q->num--; q->rear++; if(q->rear == q->max){ q->rear =0; } *x = q->que[q->rear]; if(q->num ==0){ q->front =q->rear; } return (0); } } キューを実現する構造体がこのようになっています。 typedef struct { int max; /* キューのサイズ */ int num; /* 現在の要素数 */ int front; /* 先頭要素カーソル */ int rear; /* 末尾要素カーソル */ int *que; /* キュー(の先頭要素へのポインタ) */ } Queue;

専門家に質問してみよう