🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: pl.comp.lang.c
20 messages
20 total messages Started by Borneq Sat, 21 May 2016 09:33
Opcje fopen
#308583
Author: Borneq
Date: Sat, 21 May 2016 09:33
7 lines
1126 bytes
Więc jest "rb" - czytanie binarne
"wb" - rewrite - zeruje plik
chyba też jest append "ab" - dopisywanie na końcu
A jak zrobić coś takiego:
plik ma 18 giga, ustawiam się w pozycji 10 giga i zaczynam zapisywać:
gdybym zapisał 1 bajt- plik maiłby 10 giga zamiast 18.
Ale gdy zapiszę teraz 10 giga plik będzie miał 20 giga
Re: Opcje fopen
#308584
Author: M.M.
Date: Sat, 21 May 2016 09:35
10 lines
1719 bytes
On Saturday, May 21, 2016 at 11:33:15 AM UTC+2, Borneq wrote:
> Więc jest "rb" - czytanie binarne
> "wb" - rewrite - zeruje plik
> chyba też jest append "ab" - dopisywanie na końcu
> A jak zrobić coś takiego:
> plik ma 18 giga, ustawiam się w pozycji 10 giga i zaczynam zapisywać:
> gdybym zapisał 1 bajt- plik maiłby 10 giga zamiast 18.
> Ale gdy zapiszę teraz 10 giga plik będzie miał 20 giga

może funkcja fseek, a w ogóle to wszystkie funkcjie 64-ro bitowe
Re: Opcje fopen
#308585
Author: Sebastian Biały
Date: Sat, 21 May 2016 09:56
7 lines
1134 bytes
On 2016-05-21 11:33, Borneq wrote:
> plik ma 18 giga, ustawiam się w pozycji 10 giga i zaczynam zapisywać:
> gdybym zapisał 1 bajt- plik maiłby 10 giga zamiast 18.

http://man7.org/linux/man-pages/man2/truncate.2.html

Nie każdy filesystem to obsługuje.
Re: Opcje fopen
#308586
Author: Mateusz Viste
Date: Sat, 21 May 2016 09:57
15 lines
1442 bytes
On 21/05/2016 11:33, Borneq wrote:
> A jak zrobić coś takiego:
> plik ma 18 giga, ustawiam się w pozycji 10 giga i zaczynam zapisywać:
> gdybym zapisał 1 bajt- plik maiłby 10 giga zamiast 18.

IMHO nie ma takiej opcji w czystym C. Musisz przepisać twoje 10G do 
innego pliku, usunąć oryginał, i zmienić nazwę pliku tymczasowego na ten 
oryginalny.

Alternatywnie istnieje też taka opcja (dużo szybsza):
http://linux.die.net/man/2/ftruncate

...ale to już nie jest ANSI C.

Mateusz
Re: Opcje fopen
#308587
Author: Borneq
Date: Sat, 21 May 2016 10:15
8 lines
1191 bytes
W dniu 21.05.2016 o 11:57, Mateusz Viste pisze:
> Alternatywnie istnieje też taka opcja (dużo szybsza):
> http://linux.die.net/man/2/ftruncate
>
> ...ale to już nie jest ANSI C.

nie musi to być czyste ANSI C, ale aby działało zarówno w Linuxie 
(docelowo) jak i pod Windows (do testów).
Re: Opcje fopen
#308601
Author: AK
Date: Sat, 21 May 2016 16:05
10 lines
1327 bytes
Użytkownik "Borneq" <borneq@antyspam.hidden.pl> napisał:
> Więc jest "rb" - czytanie binarne
> "wb" - rewrite - zeruje plik
> chyba też jest append "ab" - dopisywanie na końcu
> A jak zrobić coś takiego:

Moze by tak poczytal podrzadnie o fopen? Hę? (szczegolnie o +).
To przeciez _zupelne podstawy_!

AK 
Re: Opcje fopen
#308595
Author: AK
Date: Sat, 21 May 2016 16:07
7 lines
1209 bytes
Użytkownik "Mateusz Viste" <mateusz.viste@localhost> napisał:

> IMHO nie ma takiej opcji w czystym C.

No naprawde człek sie uczy całe życie :)

AK 
Re: Opcje fopen
#308602
Author: Sebastian Biały
Date: Sat, 21 May 2016 18:14
13 lines
1470 bytes
On 2016-05-21 18:05, AK wrote:
> Moze by tak poczytal podrzadnie o fopen? Hę? (szczegolnie o +).

Ja sobie wlasnie czytam z ciekawości i nikt nie wspomina o "+" jako 
funckjonalnosci od *obcinania* pliku w *konkretnym* miejscu. Owszem są 
rózne flagi np. w glibc poza standardem. Z resztą nie wiadomo jak podać 
do fopen offset.

> To przeciez _zupelne podstawy_!

Możesz pokazać jak za pomocą fopen obciąć ostatnie 5 bajtów w pliku 
który ma rozmiar 20 bajtów i zapisać tylko jeden bajt dostając plik o 
rozmiarze 16 bajtów?
Re: Opcje fopen
#308597
Author: Mateusz Viste
Date: Sat, 21 May 2016 19:11
14 lines
1382 bytes
On 21/05/2016 18:07, AK wrote:
>> IMHO nie ma takiej opcji w czystym C.
>
> No naprawde człek sie uczy całe życie :)
>
> AK

Wyczuwam sarkazm. Albo kolega nie zrozumiał pytania, albo wie o czymś o 
czym ja nie wiem.

W jaki sposób zatem obciąć plik w dowolnie wybranym offsecie zgodnie z 
ISO/IEC 9899:1990 ?

Mateusz
Re: Opcje fopen
#308598
Author: M.M.
Date: Sat, 21 May 2016 23:14
19 lines
1901 bytes
On Saturday, May 21, 2016 at 9:11:19 PM UTC+2, Mateusz Viste wrote:
> On 21/05/2016 18:07, AK wrote:
> >> IMHO nie ma takiej opcji w czystym C.
> >
> > No naprawde człek sie uczy całe życie :)
> >
> > AK
> 
> Wyczuwam sarkazm. Albo kolega nie zrozumiał pytania, albo wie o czymś o 
> czym ja nie wiem.
> 
> W jaki sposób zatem obciąć plik w dowolnie wybranym offsecie zgodnie z 
> ISO/IEC 9899:1990 ?
> 
> Mateusz

Ja początkowo też nie zrozumiałem pytania, bo wydało mi się 
baaaardzo dziwne, gdy ktoś tak kurczowo się iso.
Pozdrawiam
Re: Opcje fopen
#308588
Author: Borneq
Date: Sun, 22 May 2016 06:22
24 lines
1678 bytes
W dniu 21.05.2016 o 12:15, Borneq pisze:
> W dniu 21.05.2016 o 11:57, Mateusz Viste pisze:
>> Alternatywnie istnieje też taka opcja (dużo szybsza):
>> http://linux.die.net/man/2/ftruncate
>>
>> ...ale to już nie jest ANSI C.
>
> nie musi to być czyste ANSI C, ale aby działało zarówno w Linuxie
> (docelowo) jak i pod Windows (do testów).
>
pod Windows próbuję:
void truncate(char *path, uint64_t position)
{
	LARGE_INTEGER lr;
	lr.QuadPart = position;
	OFSTRUCT ofstruct;
	HANDLE hFile = OpenFile(path, &ofstruct, OF_WRITE);
	SetFilePointer(hFile, lr.LowPart, &lr.HighPart, FILE_BEGIN);
	SetEndOfFile(hFile);
	CloseHandle(hFile);
}

Ale błąd bo OpenFile() chce podawać HFILE a nie HANDLE, natomiast 
pozostałe funkcje chcą HANDLE.
Re: Opcje fopen
#308589
Author: Borneq
Date: Sun, 22 May 2016 06:33
7 lines
1267 bytes
W dniu 22.05.2016 o 08:22, Borneq pisze:
> Ale błąd bo OpenFile() chce podawać HFILE a nie HANDLE, natomiast
> pozostałe funkcje chcą HANDLE.

powinno być
HANDLE hFile = CreateFileA(path,GENERIC_WRITE, 
0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
Re: Opcje fopen
#308590
Author: M.M.
Date: Sun, 22 May 2016 08:12
28 lines
2782 bytes
On Sunday, May 22, 2016 at 8:33:26 AM UTC+2, Borneq wrote:
> W dniu 22.05.2016 o 08:22, Borneq pisze:
> > Ale błąd bo OpenFile() chce podawać HFILE a nie HANDLE, natomiast
> > pozostałe funkcje chcą HANDLE.
> 
> powinno być
> HANDLE hFile = CreateFileA(path,GENERIC_WRITE, 
> 0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);

Może to ze stacka będzie bardziej przenośne?

http://stackoverflow.com/questions/873454/how-to-truncate-a-file-in-c

[
If you want to preserve the previous contents of the file up to some length (a length bigger than zero, which other answers provide), then POSIX provides the truncate() and ftruncate() functions for the job.

#include <unistd.h>
int ftruncate(int fildes, off_t length);
int truncate(const char *path, off_t length);

The name indicates the primary purpose - shortening a file. But if the specified length is longer than the previous length, the file grows (zero padding) to the new size. Note that ftruncate() works on a file descriptor, not a FILE *; you could use:

if (ftruncate(fileno(fp), new_length) != 0) ...error handling...

However, you should be aware that mixing file stream (FILE *) and file descriptor (int) access to a single file is apt to lead to confusion — see the comments for some of the issues. This should be a last resort.

It is likely, though, that for your purposes, truncate on open is all you need, and for that, the options given by others will be sufficient.
]
Re: Opcje fopen
#308592
Author: Mateusz Viste
Date: Sun, 22 May 2016 08:34
16 lines
1809 bytes
On 22/05/2016 10:12, M.M. wrote:
> Może to ze stacka będzie bardziej przenośne?
>
> http://stackoverflow.com/questions/873454/how-to-truncate-a-file-in-c

Dokładnie to sugerowałem, ale OP pytał o rozwiązanie działające także na 
Windows, pytanie czy Mingw wspiera ftruncate() i czy faktycznie działa 
niezależnie od tego czy plik jest na NTFS, VFAT czy czymkolwiek innym to 
pewnego rodzaju loteria.

Jeśli ma działać zawsze, wszędzie i nie musi być szybko - trzeba 
przepisywać.
Jeśli ma być szybkie i skuteczne - ftruncate64(), ale tu trzeba mocno 
kontrolować na czym produkt końcowy będzie działać i ostro testować.

Mateusz
Re: Opcje fopen
#308593
Author: AK
Date: Sun, 22 May 2016 17:17
28 lines
1787 bytes
Użytkownik "Borneq" <borneq@antyspam.hidden.pl> napisał:

> nie musi to być czyste ANSI C, ale aby działało zarówno w Linuxie (docelowo) jak i pod Windows (do 
> testów).

Ehh.. Mlodziezy Mlodziezy.. :(

#include <stdio.h>

char buffer[] = "xyz";

int main()
{
   FILE* f;
   f = fopen("z.txt", "rb+");
   fseek(f, 10, SEEK_SET);
   fwrite(buffer, sizeof(buffer[0]), sizeof(buffer), f);
   fflush(f);
   chsize(fileno(f), ftell(f) - 1);
   fclose(f);
   return 0;
}

PS: chsize jest (o ile pamietam) Posixowa, ale na Windows tez jest (zarowno mingw jak i VC - Borland 
chyba tez).
PS1: Nie pytac mnie wiecej prosze, bo z C zerwalem na dobre (noo. prawie..) 4 lata temu.

AK
Re: Opcje fopen
#308599
Author: AK
Date: Sun, 22 May 2016 17:23
13 lines
1708 bytes
Użytkownik "M.M." <mmarszik@gmail.com> napisał:

> Ja początkowo też nie zrozumiałem pytania, bo wydało mi się
> baaaardzo dziwne, gdy ktoś tak kurczowo się iso.

Gratuluje.  Dobre podejscie.
Czasem zupelnie nie ma sensu kurczowe trzymanie sie ISO.
ISO ma w cholere wad i braków, a i zadna nietykalna swietoscia nie jest.
Nalezy sie "zaledwie" bardzo starac byc zgodnym z ISO, ale zeby
w celu zgodnosci z nim przepisywac (zwlaszcza gigabajtowy:) plik to juz
delikatie mowiac przesada.

AK
Re: Opcje fopen
#308594
Author: AK
Date: Sun, 22 May 2016 17:27
9 lines
1408 bytes
Użytkownik "AK" <nobody@nowhere.com> napisał;

> PS: chsize jest (o ile pamietam) Posixowa, ale na Windows tez jest (zarowno mingw jak i VC - 
> Borland chyba tez).

Mozna tez pokombinowac z freeopen(), ew dup(), fdopen itp, i podobnymi technikami, ale nie polecm 
(bo i po co?).

AK
Re: Opcje fopen
#308591
Author: Mateusz Viste
Date: Sun, 22 May 2016 17:53
34 lines
1985 bytes
On 22/05/2016 19:17, AK wrote:
> #include <stdio.h>
>
> char buffer[] = "xyz";
>
> int main()
> {
>    FILE* f;
>    f = fopen("z.txt", "rb+");
>    fseek(f, 10, SEEK_SET);
>    fwrite(buffer, sizeof(buffer[0]), sizeof(buffer), f);
>    fflush(f);
>    chsize(fileno(f), ftell(f) - 1);
>    fclose(f);
>    return 0;
> }

Niestety, podany kod się nie kompiluje.

mateusz:~> gcc ak.c -o ak
/tmp/cctGhGNg.o: In function `main':
t.c:(.text+0x80): undefined reference to `chsize'
collect2: error: ld returned 1 exit status
mateusz:~> uname -a
Linux 4.1.20-11 SMP Fri Mar 18 14:42:07 UTC 2016 x86_64 GNU/Linux

Widzę jednak, że na Windowsach coś takiego istnieje:
int _chsize(int fd, long size);

Ale OP pytał o coś co docelowa będzie działać na Linuksie. Do tego drugi 
problem: mowa była o wielo-gigabajtowym pliku, a funkcja którą 
proponujesz jest ograniczona do 2G-1.

Mateusz
Re: Opcje fopen
#308596
Author: Borneq
Date: Sun, 22 May 2016 18:05
30 lines
1668 bytes
W dniu 22.05.2016 o 19:17, AK pisze:
>   chsize(fileno(f), ftell(f) - 1);

void truncatePath(const char *path, uint64_t position)
{
#ifdef _WIN32
	LARGE_INTEGER lr;
	lr.QuadPart = position;
	OFSTRUCT ofstruct;
	HANDLE hFile = CreateFileA(path, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 
FILE_ATTRIBUTE_NORMAL, NULL);
	SetFilePointer(hFile, lr.LowPart, &lr.HighPart, FILE_BEGIN);
	SetEndOfFile(hFile);
	CloseHandle(hFile);
#else
	truncate64(path, position);
#endif
}

zdaje się #include <unistd.h>, podam co u mnie:
#ifdef _WIN32
#include <Windows.h>
#else
#include <sys/statvfs.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <linux/limits.h>
#include <dirent.h>
#endif
Re: Opcje fopen
#308600
Author: Mateusz Viste
Date: Sun, 22 May 2016 18:07
16 lines
2024 bytes
On 22/05/2016 19:23, AK wrote:
> Czasem zupelnie nie ma sensu kurczowe trzymanie sie ISO.
> ISO ma w cholere wad i braków, a i zadna nietykalna swietoscia nie jest.

Oczywiście - wszystko zależy od potrzeby, kontekstu, założeń... Nie 
chodzi tu o żadne trzymanie się standardu za wszelką cenę.

W mojej pierwszej odpowiedzi napisałem iż w ramach standardu można tylko 
przepisywać, a jeśli wyjście poza C89 wchodzi w grę to należy kombinować 
z ftruncate(). To drugie podejście wiąże się jednak z ryzykiem że nie 
wszędzie to zadziała i trzeba będzie potestować to i owo. Sytuację dość 
dobrze obrazuje niedziałający kod który podałeś nieco wyżej w wątku.

A OP wybierze drogę którą uzna za najstosowniejszą do swoich potrzeb.

Mateusz
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads