Написать и прочитать объект с бинарным форматированием, U-SQL - PullRequest
0 голосов
/ 14 сентября 2018

Итак, в настоящее время я пытаюсь создать пару U-sql сценариев один, в котором определенный объект записывается в файл, другой сценарий, который считывает файл и возвращает объект обратно.

Написать скрипт U-sql:

@bloomTest =
    EXTRACT date DateTime,
            region string,
            tenantName string,
            fileName string,
            modifyingUsers string,
            firstAccess string,
            lastAccess string
    FROM "SearchLog.tsv"
    USING Extractors.Tsv();

@rs0 =
    SELECT sqlProjsend.Send.send(region) AS Obj
    FROM @bloomTest;


OUTPUT @rs0
TO "/output/bloomtestSend.csv"
USING Outputters.Csv();

Написать код сзади:

 public static class Send
    {

        public static string send(string s)
        {
            IBloomfilter bloom = new BloomFilter(52);

            bloom.Add("hello");

            byte[] bArr = Serialize(bloom);
            return "|" + BitConverter.ToString(bArr).Replace("-", "") + "|";
        }




        static byte[] Serialize(IBloomfilter bloom)
        {
            MemoryStream stream = new MemoryStream();
            IFormatter formatter = new BinaryFormatter();
            formatter.Serialize(stream, bloom);
            return stream.ToArray();
        }
    }

Сценарий получения:

@bloomTest =
    EXTRACT bloom string

    FROM "/output/bloomtestSend.csv"
    USING Extractors.Csv();

@rs0 =
    SELECT sqlProjrecv.Recieve.recv(bloom) AS bloomRes
    FROM @bloomTest;


OUTPUT @rs0
TO "/output/bloomtestRecv.csv"
USING Outputters.Csv();

Получить код сзади:

public static class Recieve
    {   
        public static string recv(string b)
        {

            string[] ss = b.Split('|');

            IBloomfilter bloom = Deserialize(StringToByteArray(ss[1]));

            string[] strings = new string[3];
            strings[0] = "nice";
            strings[1] = "world";
            strings[2] = "hello";

            string retVal = "";
            foreach(string s in strings)
            {

            }
            return retVal;
        }

        public static byte[] StringToByteArray(String hex)
        {
            int NumberChars = hex.Length;
            byte[] bytes = new byte[NumberChars / 2];
            for (int i = 0; i < NumberChars; i += 2)
                bytes[i / 2] = Convert.ToByte(hex.Substring(i, 2), 16);
            return bytes;
        }
        private static IBloomfilter Deserialize(byte[] param)
        {
            using (MemoryStream ms = new MemoryStream())
            {
                ms.Write(param, 0, param.Length);
                IFormatter br = new BinaryFormatter();
                ms.Position = 0;
                return br.Deserialize(ms) as BloomFilter;
            }
        }
    }

Ошибка, которую я получаю при попытке запустить recieve local, could not find collection __codeBehind_g4nuvpoe.vvy Что мне мало что говорит. Объект bloomfilter, который я пытаюсь отправить, работает. Я также пытался использовать точно такой же код в другом проекте без сценариев u-sql, где он отлично работает:

class Program
    {
        public static byte[] StringToByteArray(String hex)
        {
            int NumberChars = hex.Length;
            byte[] bytes = new byte[NumberChars / 2];
            for (int i = 0; i < NumberChars; i += 2)
                bytes[i / 2] = Convert.ToByte(hex.Substring(i, 2), 16);
            return bytes;
        }
        private static IBloomfilter Deserialize(byte[] param)
        {
            using (MemoryStream ms = new MemoryStream(param))
            {
                IFormatter br = new BinaryFormatter();
                return br.Deserialize(ms) as BloomFilter;
            }
        }

        static byte[] Serialize(IBloomfilter bloom)
        {
            MemoryStream stream = new MemoryStream();
            IFormatter formatter = new BinaryFormatter();
            formatter.Serialize(stream, bloom);
            return stream.ToArray();
        }


        static void Main(string[] args)
        {

            IBloomfilter bloom = new BloomFilter(51);
            bloom.Add("hello");


            byte[] ser = Serialize(bloom);
            string bloomString = BitConverter.ToString(ser).Replace("-", "");


            ser = StringToByteArray(bloomString);

            bloom = Deserialize(ser);


            string[] k = new string[4];

            k[0] = "hello";
            k[1] = "world";
            k[2] = "not";
            k[3] = "this";

            foreach(string s in k)
            {
                if (bloom.Contains(s))
                {
                    Console.WriteLine(s);
                }

            }

            Console.ReadLine();
        }
     }

Этот код работает так, как вы и ожидаете, и он не отличается функционально, как вы думаете от реализации u-sql, поэтому что-то не так с реальными скриптами?

Любые идеи приветствуются!

1 Ответ

0 голосов
/ 01 октября 2018

Я не думаю, что вы можете сделать это с таким подходом.Код U-SQL будет выполняться в «контейнере», и у вас нет доступа для чтения и записи файлов, если вы не используете экстрактор и и выходной файл.Возможно, он работает локально, но не в Azure.

Примеры пользовательских операторов можно найти здесь:

https://github.com/MicrosoftDocs/azure-docs/blob/master/articles/data-lake-analytics/data-lake-analytics-u-sql-programmability-guide.md

...