c# - 'Memory stream is not expandable' but size of array is the same? -
i trying multithread aes in c# can't seem fix weird exception. buffer sizes same still says can't expand maybe can see error file of size 101 bytes.
in while loop skip if , go inside else creating (one thread?) writes not encrypted buffer encrypted buffer. after done synchronize want write encrypted buffer file in runworkercomplete function. issue presents when try write not encrypted buffer encrypted buffer. error message puzzles me since size of second buffer created length of first buffer yet says can't expand memory!?
static list<backgroundworker> threadcompany = new list<backgroundworker>(); static list<backgroundworker> listworkers = new list<backgroundworker>(); static list<backgroundworker> listfreeworkers = new list<backgroundworker>(); static filestream fsin; static string file; static byte[] key; const int block_size = 1000; static filestream outfile; public static void encryptfile(string inputfile, string outputfile, string skey, progressbar progress) { string filename = inputfile; filename = "\\" + filename.split('\\').last(); var progres = new progress<int>(value => progress.value = value); file = outputfile + filename; fsin = new filestream(inputfile, filemode.open); outfile = new filestream(file, filemode.create); key = new unicodeencoding().getbytes(skey); (int t = 0; t < 4; t++) { backgroundworker worker = new backgroundworker(); worker.dowork += worker_dowork; worker.runworkercompleted += worker_runworkercompleted; listworkers.add(worker); listfreeworkers.add(worker); } byte[] buffer = new byte[block_size]; fileinfo fileinfo = new fileinfo(inputfile); double numblocks = math.ceiling(((double)fileinfo.length) / block_size); int ixcurrentblock = 0; while (ixcurrentblock < numblocks) { //check if free workers if (listfreeworkers.count > 0) { //get worker, remove list backgroundworker freeworker = listfreeworkers[0]; listfreeworkers.removeat(0); //read next block of file int bytes; if (ixcurrentblock < numblocks - 1) { bytes = fsin.read(buffer, ixcurrentblock * block_size, block_size); freeworker.runworkerasync(tuple.create(ixcurrentblock, buffer)); threadcompany.remove(freeworker); } else //special handling last block { messagebox.show((ixcurrentblock * block_size) + " " + (int)(fileinfo.length - ixcurrentblock * block_size)); // 0 101 bytes = fsin.read(buffer, ixcurrentblock * block_size, (int)(fileinfo.length - ixcurrentblock * block_size)); freeworker.runworkerasync(tuple.create(ixcurrentblock, new byte[(int)(fileinfo.length - ixcurrentblock * block_size)])); threadcompany.remove(freeworker); } //now pass worker //advance next block ixcurrentblock++; //update ui status here // ... } else //no workers free { thread.sleep(50); } } //if make here have sent off blocks //now wait threads complete bool threadsrunning = false; while (threadsrunning) { threadsrunning = false; foreach (backgroundworker worker in listworkers) { threadsrunning |= worker.isbusy; } //if still running, wait , try again in 50ms if (threadsrunning) { thread.sleep(50); } } } private static void worker_dowork(object sender, doworkeventargs e) { tuple<int, byte[]> t = e.argument tuple<int, byte[]>; int blockindex = (int)t.item1; byte[] inbuffer = (byte[])t.item2; byte[] outbuffer = new byte[inbuffer.length]; //using keyword automatically close stream using (memorystream outstream = new memorystream(outbuffer)) // issue may here? { rijndaelmanaged rmcrypto = new rijndaelmanaged(); using (cryptostream cs = new cryptostream(outstream, rmcrypto.createencryptor(key, key), cryptostreammode.write)) { // want write inbuffer non encrypted outbuffer encrypted. cs.write(inbuffer, blockindex, inbuffer.length); } } e.result = tuple.create(blockindex, outbuffer); } private static void worker_runworkercompleted(object sender, runworkercompletedeventargs e) { messagebox.show(e.error.message + " "); // memory not expendable tuple<int, byte[]> t = e.result tuple<int, byte[]>; int blockindex = (int)t.item1; byte[] buffer = (byte[])t.item2; //assumes have class variable, _outfile, open filestream outfile.write(buffer, blockindex, buffer.length); outfile.close(); //add worker free workers list listfreeworkers.add((backgroundworker)sender); }
encryption , decryption arn't same size solve issue flush stream (already implied using
statement) toarray stream outbuffer.
solution
private static void worker_dowork(object sender, doworkeventargs e) { tuple<int, byte[]> t = e.argument tuple<int, byte[]>; int blockindex = (int)t.item1; byte[] inbuffer = (byte[])t.item2; byte[] outbuffer; //using keyword automatically close stream using (memorystream outstream = new memorystream()) // issue may here? { aescryptoserviceprovider rmcrypto = new aescryptoserviceprovider(); using (cryptostream cs = new cryptostream(outstream, rmcrypto.createencryptor(key, key), cryptostreammode.write)) { // want write inbuffer non encrypted outbuffer encrypted. cs.write(inbuffer, blockindex, inbuffer.length); } outbuffer = outstream.toarray(); } e.result = tuple.create(blockindex, outbuffer); }
Comments
Post a Comment