Копирование файлов на С

Модераторы: Hawk, Romeo, Absurd, DeeJayC, WinMain

Skwoogey
Сообщения: 65
Зарегистрирован: 11 янв 2016, 02:25

У меня не хочет работать второй utime(именно второй, потому что если поменять их местами, вывод все равно тем же будет, то есть первый раз при выполнении он работает, а второй раз - нет). Нигде подобного случая не нашел. В чем косяк, понять не могу. Нужна помощь.

Для справки:
utime выдает 0, если успешно, и -1 если провал.

Код: Выделить всё

#include <stdio.h>
#include <dirent.h>
#include <utime.h>

int main()
{
	int test;
	struct utimbuf tm1,tm2;
	...
	test = utime("C:\\sample2\\file1.txt",&tm2); 
	printf("%d\n",test);
	test = utime("C:\\sample1\\file1.txt",&tm1);
	printf("%d\n",test);
}
Вывод:
0
-1
Аватара пользователя
Romeo
Сообщения: 3126
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

Компилируешь MinGW, правильно? Просто функция utime исключительно линуксовая, а пути к файлам у тебя виндовые. Здесь только MinGW подходит. Я понимаю, что можно догадаться, но лучше это сразу указывать, чтобы народ голову не ломал.

Какими значениями заполняются поля tm1 и tm2? Если их не заполнять вообще, то у меня два раза -1 возвращает, и это логично.
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Skwoogey
Сообщения: 65
Зарегистрирован: 11 янв 2016, 02:25

Простите, я идиот. Я небрежно прочитал документацию к функции. В итоге оказалось, что она мне не нужна. Но все равно спасибо за помощь. Я учту ваши замечания.

P.S.
В си есть копирование файлов кроме варварского создания аналогичного и последующего побайтового копирования из оригинала в копию?
Аватара пользователя
Romeo
Сообщения: 3126
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

Если привязка с Windows позволительна, то самое простое и правильное - это вызывать CopyFile.
Если же требуется кроссплатформенное решение то, да, очевидных способов кроме как через буфер делать fread/fwrite нет.
Есть ещё вот такие варианты, но это для nix систем.
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Skwoogey
Сообщения: 65
Зарегистрирован: 11 янв 2016, 02:25

В общем, я тут пытался сделать функцию, но запоролся. Моя функция копирует файлы без содержимого. В чем проблема - понять не могу.

Код: Выделить всё

void copyfile(char *file,int mode)
{
	FILE *fp1,*fp2;
	char bak[100];
	name_maker(bak,file,mode);
	puts(bak);
	if((fp1 = fopen(bak, "rb")) == NULL)
	puts("net1");
	char file_nm[100];
	name_maker(file_nm,file,-mode);
	puts(file_nm);
	if((fp2 = fopen(file_nm,"wb")) == NULL)
	puts("net2");
	int rc;
	char k;
	while(fread(k, sizeof(k), 1,fp1) != 0)
	{
		fwrite(k, sizeof(k), 1, fp2);
	}
	fclose(fp1);
	fclose(fp2);
}
name_maker собирает строку полного пути. Он работает правильно. Переменная mode тоже для него.

Заранее спасибо.

Mingw, Win 8.1
Аватара пользователя
Romeo
Сообщения: 3126
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

Функции fread/fwrite получают адрес буфера, так что поставь амперсанд перед k.

И ещё посоветую увеличить размер буфера хотя бы до пары десятков килобайт, а желательно вообще сделать его мегабайтным.

И, кстати, почему не воспользоваться CopyFile, ведь для MinGW это не проблема? Эта функция произведёт копирование заведомо более оптимально.
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Skwoogey
Сообщения: 65
Зарегистрирован: 11 янв 2016, 02:25

Теперь у меня файлы битые получаются, судя по всему недописанные или переписанные. Они близки по размеру, но не равны.
Romeo писал(а): И, кстати, почему не воспользоваться CopyFile, ведь для MinGW это не проблема? Эта функция произведёт копирование заведомо более оптимально.
Мне нужен универсальный код.
Аватара пользователя
Romeo
Сообщения: 3126
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

"Теперь" - это после того, как буфер сделал большим?

Дело в том, что нужно писать столько, сколько вернул fread, а не весь буфер. В конце ведь буфер не полностью заполняется, и если писать его целиком, то запишешь кусок повторяющихся данных в хвосте, записанных предыдущем fread'ом.

Код: Выделить всё

char k[10000];
size_t bytesCount;
while((bytesCount = fread(k, sizeof(k), 1, fp1)) != 0)
{
    fwrite(k, bytesCount, 1, fp2);
}
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Skwoogey
Сообщения: 65
Зарегистрирован: 11 янв 2016, 02:25

Ладно. С переписанными файлами фишку понял, но недописанные все еще есть. причем, чем я больше делаю строку, тем недобор больше.
Аватара пользователя
Duncon
Сообщения: 2085
Зарегистрирован: 10 окт 2004, 14:11
Откуда: Питер
Контактная информация:

А чего условную компиляцию не использовать для универсального кода?
[syntax=Delphi] [/syntax]
Ответить