none
Программная распаковка RAR-файла

    Pregunta

  • Всем привет!

    Задача -

    Есть куча RAR-файлов, в которых сохранена текстовая информация.
    Нужно программно распаковать каждый файл, прочесть каждую строку,
    внести в нее коррективы и снова запаковать и записать в другой RAR-файл.

    Как это сделать на C#?
    martes, 27 de noviembre de 2012 12:19

Respuestas

  • 2. Файлы добавлять никакие не нужно. Достаточно только ссылки на dll

    Посмотрите тестовый проект - http://sdrv.ms/QECpCs


    Для связи [mail]

    • Marcado como respuesta QazRdx martes, 04 de diciembre de 2012 16:05
    • Desmarcado como respuesta QazRdx miércoles, 05 de diciembre de 2012 0:11
    • Marcado como respuesta QazRdx miércoles, 05 de diciembre de 2012 10:28
    • Desmarcado como respuesta QazRdx miércoles, 05 de diciembre de 2012 15:32
    • Marcado como respuesta QazRdx viernes, 07 de diciembre de 2012 3:16
    martes, 04 de diciembre de 2012 15:13
  • Можно и без BAT файла,
    из C# можно же вызывать программы с командной строкой

    Эдакий способ вызова библиотечных функций ) (на вид похоже, и из языка вызывается)

    Получатся файлы, потом их читаете,
    и опять же командной строкой из C# архивируете.

    пример:
    System.Diagnostics.Process.Start(@"F:\rar.exe -p 4428 test");

    Путь неправильный, праметры тоже, но пример правильный
    • Editado INFEL8 miércoles, 05 de diciembre de 2012 10:54
    • Marcado como respuesta QazRdx miércoles, 05 de diciembre de 2012 11:34
    • Desmarcado como respuesta QazRdx miércoles, 05 de diciembre de 2012 15:31
    • Marcado como respuesta QazRdx viernes, 07 de diciembre de 2012 3:17
    miércoles, 05 de diciembre de 2012 10:45
  • Вот вымученное решение.
    RAR - команды - http://forum.foxclub.ru/read.php?29,263057
    Всем спасибо.
    using System;
    using System.IO;
    namespace Test
    {	class Program
    	{	static	void	Main(string[] args)
    		{	string srcF, batF;
    			StreamWriter w;
    
    //	1. Создание исходного текстового файла
    			srcF=@"D:/F.txt";
    			w=new StreamWriter(srcF);
    			w.Write("И волки сыты,\nИ овцы целы,\nИ пастуху - вечная память.");
    			w.Close();
    
    //	2. Тормоз, чтобы проконтролировать исполнение?
    			Console.WriteLine("2");		Console.ReadKey();
    
    //	3. Создание и запуск архивирующего командного bat-файла
    			batF=@"D:/Pack.bat";
    			w=new StreamWriter(batF);
    
    //	4.	Командная строка - Заархивировать исходный текстовый файл
    			w.WriteLine("D:/WinRAR/Rar.exe a D:/Arj D:/F.txt");		//	-df 
    			w.Close();
    			System.Diagnostics.Process.Start(batF);
    
    //	5. Тормоз, чтобы проконтролировать исполнение?
    			Console.WriteLine("5");		Console.ReadKey();
    
    //	7. Создание и запуск разархивирующего командного bat-файла
    			batF=@"D:/UnPack.bat";
    			w=new StreamWriter(batF);
    
    //	8.	Командная строка - Разархивировать исходный текстовый файл в другую папку
    			w.WriteLine("D:/WinRAR/Rar.exe e D:/Arj D:/_");
    			w.Close();
    			System.Diagnostics.Process.Start(batF);
    }	}	}	


    • Marcado como respuesta QazRdx viernes, 07 de diciembre de 2012 3:15
    • Editado QazRdx viernes, 07 de diciembre de 2012 10:22
    viernes, 07 de diciembre de 2012 3:14
  • Можно проще:

    Process p = new Process();
    ProcessStartInfo psi = new ProcessStartInfo();
    psi.FileName = @"C:\Program Files\WinRAR\Rar.exe";
    
    //Запаковываем            
    psi.Arguments = @"a D:\Arj D:\F.txt";
    p.StartInfo = psi;
    p.Start();
    
    //Распаковываем
    psi.Arguments = @"e D:\Arj D:\F\";
    p.StartInfo = psi;
    p.Start();


    • Editado Petalvik viernes, 07 de diciembre de 2012 5:32
    • Marcado como respuesta QazRdx viernes, 07 de diciembre de 2012 8:48
    viernes, 07 de diciembre de 2012 5:19
  • Да, братцы!
    Расколупали вы мою проблему в пух и перья!
    Виртуозы!
    Последний штрих -
    при архивировании я использую ключ -df,
    удалить исходный файл после упаковки,
    а распаковываю в ту же папку, 
    в которой находится архив -
    мне так удобней, хотя возможны и другие мнения.
    Ждать завершение упаковки надо,
    поскольку процесс ассинхронный,
    хотя это нонсенс -
    распаковывать сразу после упаковки.

    using System;
    using System.Diagnostics;
    namespace Test
    {	class Program
    	{	static	void	Main(string[] args)
    { Process p = new Process(); ProcessStartInfo psi = new ProcessStartInfo(); psi.FileName = @"C:\Program Files\WinRAR\Rar.exe"; // Запаковываем psi.Arguments = @"a -df D:\Arj D:\F.txt"; p.StartInfo = psi; p.Start(); // Console.ReadKey(); p.WaitForExit()
    // Распаковываем psi.Arguments = @"e D:\Arj D:\"; p.StartInfo = psi; p.Start(); } } }





    • Marcado como respuesta QazRdx viernes, 07 de diciembre de 2012 8:48
    • Desmarcado como respuesta QazRdx viernes, 07 de diciembre de 2012 10:19
    • Editado QazRdx viernes, 07 de diciembre de 2012 10:20
    • Marcado como respuesta QazRdx viernes, 07 de diciembre de 2012 10:48
    viernes, 07 de diciembre de 2012 8:46

Todas las respuestas

  • Жаль, что не zip, так бы проще наверное, есть SharpZipLib, он раззипнет и дальше просто текст а потом зазипнет.

    Про рар не знаю.
    Может к рару можно как-то обращаться через командную строку.
    А дальше опять текст.
    martes, 27 de noviembre de 2012 12:25
  • Спасибо, полезная информация.
    Может быть стоит перейти на ZIP-файлы.
    Но пока есть RAR-архив, который нужно слегка подправить.
    martes, 27 de noviembre de 2012 12:49
  • Посмотрите тут, вроде должно помочь.
    martes, 27 de noviembre de 2012 13:08
    Moderador
  • Да, возможно это и есть то, что надо,
    но не хочет работать, говорит что памяти мало.
    Хотя не понятно почему -
    32-битная система, установлено 2 Гб, свободно 70%, т.е. 1.4 Гб,
    файл для распаковки - 300 Мб в распакованном виде,
    а в запакованном - 40 Мб.
    Вроде должно хватать.
    martes, 27 de noviembre de 2012 20:01
  • Привет.

    Попробуйте воспользоваться библиотеками с codeplex - NUnrar - Unrar in pure C# и SevenZipSharp и также SharpCompress - a fully native C# library for RAR, 7Zip, Zip, Tar, GZip, BZip2

    Думаю одна из них вам точно должна подойти.


    Для связи [mail]

    lunes, 03 de diciembre de 2012 8:51
  • Спасибо, Дмитрий!

    Началась темная полоса в моей жизни...
    В SharpCompress-е используется сборка Microsoft.VisualStudio, которой у меня нет.
    Microsoft, главное, есть, а Microsoft.VisualStudio - нет, наверное из-за того, что у меня Express-версия.
    В NUnrar-е нет сборки NUnrar.IO, NUnrar есть, а NUnrar.IO - нет.
    Соответственно по крайней мере 2 класса - IRarExtractionListener, RarReaderVolume, не содержат свойств,
    которые используются в предлагаемых программах - классы есть, а нужных свойств нет - фантастика.
    С SevenZipSharp - ом тоже нелады.
    Видимо, придется пользоваться старым добрым командным bat-файлом,
    надо только вспомнить, как там что делается - со времен Autoexec.bat-а я туда не совался.


    • Editado QazRdx martes, 04 de diciembre de 2012 3:45
    martes, 04 de diciembre de 2012 3:29
  • Под какой проект и версию .net вы подключаете SharpComperss? У меня WinForms 4.0 без проблем подключается эта библиотека (SharpCompress.dll) и распаковывает архив.

    Для связи [mail]

    martes, 04 de diciembre de 2012 10:03
  • Консольный, как и в примере, который там разбирается.
    MSVS 2010 v10.0.3... Express,
    MS.NET Framework v 4.0.3...

    Может я не туда лезу.

    1. Я скачал файл SharpCompress 0.8.1 с вкладки DOWNLOADS,
    после распаковки получил 4 библиотеки-
    SharpCompress.dll, SharpCompress.3.5.dll, SharpCompress.Silverlight.dll, SharpCompress.WP7.dll

    2. Создал проект и добавил в него файлы,
    текст которых находится в выпадающем меню
    SharpCompress.Test, -
       ArchiveTests.cs    
       Program.cs    
       ReaderTests.cs    
       RewindableStreamTest.cs    
       SharpCompress.Test.csproj    
       TestBase.cs    
       TestStream.cs   
       WriterTests.cs   

    3. Сначала добавил к проекту ссылку на первую библиотеку из п.1 - не получилось,
    потом для порядка - по-порядку все остальные - тот же результат.
    Об ошибках я говорил в предыдущем своем посте.


    • Editado QazRdx martes, 04 de diciembre de 2012 13:50
    martes, 04 de diciembre de 2012 13:48
  • 2. Файлы добавлять никакие не нужно. Достаточно только ссылки на dll

    Посмотрите тестовый проект - http://sdrv.ms/QECpCs


    Для связи [mail]

    • Marcado como respuesta QazRdx martes, 04 de diciembre de 2012 16:05
    • Desmarcado como respuesta QazRdx miércoles, 05 de diciembre de 2012 0:11
    • Marcado como respuesta QazRdx miércoles, 05 de diciembre de 2012 10:28
    • Desmarcado como respuesta QazRdx miércoles, 05 de diciembre de 2012 15:32
    • Marcado como respuesta QazRdx viernes, 07 de diciembre de 2012 3:16
    martes, 04 de diciembre de 2012 15:13
  • Да, это то, что нужно!
    Жизнь налаживается!
    Большое спасибо, Дмитрий!

    martes, 04 de diciembre de 2012 16:05
  • I am sorry!
    Еще один вопрос - как архивировать?
    По аналогии с Вашим примером я сделал программу -

    using System;
    using System.IO;	
    using SharpCompress.Common;	
    using SharpCompress.Writer;
    using SharpCompress.IO;
    namespace testSharp
    {	class Program
    	{	static	void	Main(string[] args)
    		{	string f="D:\\_A";	// В этой папке 2 текстовых файла для архивирования
    			using (Stream stream = File.OpenWrite(f))
    			{	var writer = WriterFactory.Open(stream,ArchiveType.Rar,CompressionType.Rar);
    				writer.WriteAll(f);
    }	}	}	}
    Затыкается на инициации потока, using (Stream...), говорит - Отказано в доступе по пути "D:\_A".
    В свойствах этой папки я к ней доступ открыл. Все равно не хочет работать.


    • Editado QazRdx miércoles, 05 de diciembre de 2012 0:35
    miércoles, 05 de diciembre de 2012 0:28
  • К сожалению, так как rar - пропиетарный платный формат, библиотеки запаковывать в него не умеют. Для этого нужно либо использовать сам WinRar, либо искать платную библиотеку (скорее всего какой-то платный компонент от самого WinRar), которая это умеет делать.

    Для связи [mail]

    • Marcado como respuesta QazRdx miércoles, 05 de diciembre de 2012 10:28
    • Desmarcado como respuesta QazRdx miércoles, 05 de diciembre de 2012 15:32
    miércoles, 05 de diciembre de 2012 7:15
  • А чем мой вариант с командной строкой не подходит (предложенный ранее)?
    подумаешь там нужен сам рар, но для разовых действий вполне сойдёт.

    вот 1-е что яндекс выдал
    http://forum.foxclub.ru/read.php?29,263057
    • Marcado como respuesta QazRdx miércoles, 05 de diciembre de 2012 10:28
    • Desmarcado como respuesta QazRdx miércoles, 05 de diciembre de 2012 15:32
    miércoles, 05 de diciembre de 2012 7:46
  • "...rar - пропРиетарный платный формат..."
    Вот всегда так - "где капля блага, там на страже...",
    "...вариант с командной строкой..." - конечно же это вариант,
    я тоже говорил ранее про "старый добрый командный bat-файл".
    А в данном случае другого варианта для архивирования, видимо, не остается,
    и, Вы правы, разовая архивация одного файла в сутки -
    это даже вручную не утомительно, тем более с помощью командного файла.
    А вот программный вариант разархивирования мне очень удобен
    для многократной переобработки всего массива файлов.
    INFEL8, Ваша ссылочка очень к месту.
    Всем спасибо - помогли!

    miércoles, 05 de diciembre de 2012 10:26
  • Можно и без BAT файла,
    из C# можно же вызывать программы с командной строкой

    Эдакий способ вызова библиотечных функций ) (на вид похоже, и из языка вызывается)

    Получатся файлы, потом их читаете,
    и опять же командной строкой из C# архивируете.

    пример:
    System.Diagnostics.Process.Start(@"F:\rar.exe -p 4428 test");

    Путь неправильный, праметры тоже, но пример правильный
    • Editado INFEL8 miércoles, 05 de diciembre de 2012 10:54
    • Marcado como respuesta QazRdx miércoles, 05 de diciembre de 2012 11:34
    • Desmarcado como respuesta QazRdx miércoles, 05 de diciembre de 2012 15:31
    • Marcado como respuesta QazRdx viernes, 07 de diciembre de 2012 3:17
    miércoles, 05 de diciembre de 2012 10:45
  • "...из C# можно же вызывать программы с командной строкой..."
    Я или забыл, или просто не знаю!
    Поясните, пожалуйста, лучше с примером!

    • Editado QazRdx miércoles, 05 de diciembre de 2012 11:07
    miércoles, 05 de diciembre de 2012 11:05
  • Ну вот у меня там в сообщении отредактированном.
    Всё как в командной строке пишете, так и тут.

    1-й параметр - имя исполняемого файла.
    дальше чего там по ссылке у меня про команды архиватора

    я от старой своей проги параметры для примера скопировал, не обращайте внимания,
    просто для примера.
    (итого у меня там 4 параметра, включая имя файла, разделяется пробелами, как обычно)
    • Editado INFEL8 miércoles, 05 de diciembre de 2012 11:13
    miércoles, 05 de diciembre de 2012 11:11
  • Замечательно.
    Началась светлая полоса в моей жизни.

    miércoles, 05 de diciembre de 2012 11:36
    • Editado INFEL8 miércoles, 05 de diciembre de 2012 11:58
    miércoles, 05 de diciembre de 2012 11:51
  • В точку!
    miércoles, 05 de diciembre de 2012 12:46
  • Да, рано порадовались!
    Команды из программы в командном режиме работают,
    а в программном - нет.

    using System;
    using System.IO;
    namespace test
    { class Program { static void Main(string[] args) { string S; S=@"C:\Program Files\WinRAR\Rar.exe a D:A D:A.txt"; // S=@"C:\Program Files\WinRAR\Rar.exe e D:A D:"; System.Diagnostics.Process.Start(S); } } }


    • Editado QazRdx miércoles, 05 de diciembre de 2012 15:34
    miércoles, 05 de diciembre de 2012 15:30
  • думаю, что не совсем так команда записана

    тут пробел вкрался в пути,
    а вот если отправить рар в папку где нет пробела, то может и сработает.

    Может быть ещё как-то можно параметрами задать нормально, а не просто строкой.

    О, и сразу нашлось.
    Используйте другую перегрузку этого метода.
    вон их сколько много
    http://msdn.microsoft.com/ru-ru/library/vstudio/system.diagnostics.process.start(v=vs.100).aspx


    Тут наверное можно и с пробелом путь,
    а вот в той длинной строке наверное нельзя
    • Editado INFEL8 miércoles, 05 de diciembre de 2012 17:24
    miércoles, 05 de diciembre de 2012 17:21
  • Вот вымученное решение.
    RAR - команды - http://forum.foxclub.ru/read.php?29,263057
    Всем спасибо.
    using System;
    using System.IO;
    namespace Test
    {	class Program
    	{	static	void	Main(string[] args)
    		{	string srcF, batF;
    			StreamWriter w;
    
    //	1. Создание исходного текстового файла
    			srcF=@"D:/F.txt";
    			w=new StreamWriter(srcF);
    			w.Write("И волки сыты,\nИ овцы целы,\nИ пастуху - вечная память.");
    			w.Close();
    
    //	2. Тормоз, чтобы проконтролировать исполнение?
    			Console.WriteLine("2");		Console.ReadKey();
    
    //	3. Создание и запуск архивирующего командного bat-файла
    			batF=@"D:/Pack.bat";
    			w=new StreamWriter(batF);
    
    //	4.	Командная строка - Заархивировать исходный текстовый файл
    			w.WriteLine("D:/WinRAR/Rar.exe a D:/Arj D:/F.txt");		//	-df 
    			w.Close();
    			System.Diagnostics.Process.Start(batF);
    
    //	5. Тормоз, чтобы проконтролировать исполнение?
    			Console.WriteLine("5");		Console.ReadKey();
    
    //	7. Создание и запуск разархивирующего командного bat-файла
    			batF=@"D:/UnPack.bat";
    			w=new StreamWriter(batF);
    
    //	8.	Командная строка - Разархивировать исходный текстовый файл в другую папку
    			w.WriteLine("D:/WinRAR/Rar.exe e D:/Arj D:/_");
    			w.Close();
    			System.Diagnostics.Process.Start(batF);
    }	}	}	


    • Marcado como respuesta QazRdx viernes, 07 de diciembre de 2012 3:15
    • Editado QazRdx viernes, 07 de diciembre de 2012 10:22
    viernes, 07 de diciembre de 2012 3:14
  • Так а что через другую перегрузку метода Start не работает?
    Я попробую тогда, если не работает.

    (ну чтобы без бат файла)
    Надо только строчки на которых не работает.
    • Editado INFEL8 viernes, 07 de diciembre de 2012 4:53
    viernes, 07 de diciembre de 2012 4:42
  • Можно проще:

    Process p = new Process();
    ProcessStartInfo psi = new ProcessStartInfo();
    psi.FileName = @"C:\Program Files\WinRAR\Rar.exe";
    
    //Запаковываем            
    psi.Arguments = @"a D:\Arj D:\F.txt";
    p.StartInfo = psi;
    p.Start();
    
    //Распаковываем
    psi.Arguments = @"e D:\Arj D:\F\";
    p.StartInfo = psi;
    p.Start();


    • Editado Petalvik viernes, 07 de diciembre de 2012 5:32
    • Marcado como respuesta QazRdx viernes, 07 de diciembre de 2012 8:48
    viernes, 07 de diciembre de 2012 5:19
  • Ну вот и другая перегрузка,
    правда там порсто статический метод,
    а тут не статический.
    (Так что немного не того метода =) , ну это уже не важно)

    Да, кстати, попробовал и у меня работает без бат файлов
    ,
    ровно как у Вас написано.
    Только подчёркивание убрал из пути разархивирования.
    Лень было папку такую создавать.

    А если бы путь до WinRAR.exe был с пробелами,
    то такую перегрузку можно было сделать:
    Start(<путь>, <параметры>);
    Ну или через StartInfo (как предложили).
    Start и StartInfo тоже принимает.

    ПС.
    Я после каждого Start() ставил WaitForExit() ,
    чтобы успевало заархивировать хотя бы.
    • Editado INFEL8 viernes, 07 de diciembre de 2012 5:35
    viernes, 07 de diciembre de 2012 5:34
  • ПС.
    Я после каждого Start() ставил WaitForExit() ,
    чтобы успевало заархивировать хотя бы.
    Верно, чтобы дождаться завершения процесса нужно вызывать WaitForExit. Но наверняка запаковка и распаковка в реальном приложении будут происходить в разных местах кода, поэтому там не нужно будет ждать.
    viernes, 07 de diciembre de 2012 7:04
  • Да, братцы!
    Расколупали вы мою проблему в пух и перья!
    Виртуозы!
    Последний штрих -
    при архивировании я использую ключ -df,
    удалить исходный файл после упаковки,
    а распаковываю в ту же папку, 
    в которой находится архив -
    мне так удобней, хотя возможны и другие мнения.
    Ждать завершение упаковки надо,
    поскольку процесс ассинхронный,
    хотя это нонсенс -
    распаковывать сразу после упаковки.

    using System;
    using System.Diagnostics;
    namespace Test
    {	class Program
    	{	static	void	Main(string[] args)
    { Process p = new Process(); ProcessStartInfo psi = new ProcessStartInfo(); psi.FileName = @"C:\Program Files\WinRAR\Rar.exe"; // Запаковываем psi.Arguments = @"a -df D:\Arj D:\F.txt"; p.StartInfo = psi; p.Start(); // Console.ReadKey(); p.WaitForExit()
    // Распаковываем psi.Arguments = @"e D:\Arj D:\"; p.StartInfo = psi; p.Start(); } } }





    • Marcado como respuesta QazRdx viernes, 07 de diciembre de 2012 8:48
    • Desmarcado como respuesta QazRdx viernes, 07 de diciembre de 2012 10:19
    • Editado QazRdx viernes, 07 de diciembre de 2012 10:20
    • Marcado como respuesta QazRdx viernes, 07 de diciembre de 2012 10:48
    viernes, 07 de diciembre de 2012 8:46
  • Ждать надо, думается, так как если файл будет чуть побольше,
    то Вы будете распаковывать файл, который ещё не упаковался.
    viernes, 07 de diciembre de 2012 9:11
  • Да, действительно.
    Значит запускается асинхронность.
    Примем к сведению.
    Спасибо!

    viernes, 07 de diciembre de 2012 10:08