Информация об изменениях

Сообщение Re[5]: Как в одну строку кода прочитать содержимое файла в м от 07.01.2024 18:59

Изменено 07.01.2024 20:20 rg45

Re[5]: Как в одну строку кода прочитать содержимое файла в м
Здравствуйте, Kluev, Вы писали:

K>Т.е. данный говнокод может легко рыгнуть уже на целочисленном переполнении, не говоря уже о других проблемах озвученных другими собеседниками выше.


Да ты говнокода не видел, походу. Хочешь увидеть говнокод — загляни в реализацию File.ReadAllBytes. Вот где индусятина буйным цветом.

  File.ReadAllBytes (C#)
    public static byte[] ReadAllBytes(string path)
    {
        if (1 == 0)
        {
        }
        FileOptions options = FileOptions.SequentialScan;
        using SafeFileHandle safeFileHandle = OpenHandle(path, FileMode.Open, FileAccess.Read, FileShare.Read, options, 0L);
        long num = 0L;
        if (safeFileHandle.CanSeek && (num = safeFileHandle.GetFileLength()) > 2147483591)
        {
            throw new IOException(SR.IO_FileTooLong2GB);
        }
        if (num == 0L)
        {
            return ReadAllBytesUnknownLength(safeFileHandle);
        }
        int num2 = 0;
        int num3 = (int)num;
        byte[] array = new byte[num3];
        while (num3 > 0)
        {
            int num4 = RandomAccess.ReadAtOffset(safeFileHandle, array.AsSpan(num2, num3), num2);
            if (num4 == 0)
            {
                ThrowHelper.ThrowEndOfFileException();
            }
            num2 += num4;
            num3 -= num4;
        }
        return array;
    }

    private static byte[] ReadAllBytesUnknownLength(SafeFileHandle sfh)
    {
        byte[] array = null;
        Span<byte> span = stackalloc byte[512];
        try
        {
            int num = 0;
            while (true)
            {
                if (num == span.Length)
                {
                    uint num2 = (uint)(span.Length * 2);
                    if ((long)num2 > 2147483591L)
                    {
                        num2 = (uint)Math.Max(2147483591, span.Length + 1);
                    }
                    byte[] array2 = ArrayPool<byte>.Shared.Rent((int)num2);
                    span.CopyTo(array2);
                    byte[] array3 = array;
                    span = (array = array2);
                    if (array3 != null)
                    {
                        ArrayPool<byte>.Shared.Return(array3);
                    }
                }
                int num3 = RandomAccess.ReadAtOffset(sfh, span.Slice(num), num);
                if (num3 == 0)
                {
                    break;
                }
                num += num3;
            }
            return span.Slice(0, num).ToArray();
        }
        finally
        {
            if (array != null)
            {
                ArrayPool<byte>.Shared.Return(array);
            }
        }
    }

Классная работа ученика школы информационных технологий для умственно отсталых. Зато всё большими буквами, ага.


И кстати, мой "говнокод" спокойно загружает файлы размером свыше 2ГБ, а у вашей чудесной File.ReadAllBytes слетает кабина:

Unhandled exception. System.IO.IOException: The file is too long. This operation is currently limited to supporting files less than 2 gigabytes in size.
   at System.IO.File.ReadAllBytes(String path)
   at ConsoleApp1.Program.Main(String[] args) in E:\Development\VS2022\ConsoleApp1\Program.cs:line 8

E:\Development\VS2022\ConsoleApp1\bin\Release\net8.0\ConsoleApp1.exe (process 644) exited with code -532462766.
Press any key to close this window . . .


Тебя все еще удивляет, почему в std нет аналога File.ReadAllBytes? Отвечаю: потому что нафиг мне не упало в std такое счастье.
Re[5]: Как в одну строку кода прочитать содержимое файла в м
Здравствуйте, Kluev, Вы писали:

K>Т.е. данный говнокод может легко рыгнуть уже на целочисленном переполнении, не говоря уже о других проблемах озвученных другими собеседниками выше.


Да ты говнокода не видел, походу. Хочешь увидеть говнокод — загляни в реализацию File.ReadAllBytes. Вот где индусятина буйным цветом.

  File.ReadAllBytes (C#)
    public static byte[] ReadAllBytes(string path)
    {
        if (1 == 0)
        {
        }
        FileOptions options = FileOptions.SequentialScan;
        using SafeFileHandle safeFileHandle = OpenHandle(path, FileMode.Open, FileAccess.Read, FileShare.Read, options, 0L);
        long num = 0L;
        if (safeFileHandle.CanSeek && (num = safeFileHandle.GetFileLength()) > 2147483591)
        {
            throw new IOException(SR.IO_FileTooLong2GB);
        }
        if (num == 0L)
        {
            return ReadAllBytesUnknownLength(safeFileHandle);
        }
        int num2 = 0;
        int num3 = (int)num;
        byte[] array = new byte[num3];
        while (num3 > 0)
        {
            int num4 = RandomAccess.ReadAtOffset(safeFileHandle, array.AsSpan(num2, num3), num2);
            if (num4 == 0)
            {
                ThrowHelper.ThrowEndOfFileException();
            }
            num2 += num4;
            num3 -= num4;
        }
        return array;
    }

    private static byte[] ReadAllBytesUnknownLength(SafeFileHandle sfh)
    {
        byte[] array = null;
        Span<byte> span = stackalloc byte[512];
        try
        {
            int num = 0;
            while (true)
            {
                if (num == span.Length)
                {
                    uint num2 = (uint)(span.Length * 2);
                    if ((long)num2 > 2147483591L)
                    {
                        num2 = (uint)Math.Max(2147483591, span.Length + 1);
                    }
                    byte[] array2 = ArrayPool<byte>.Shared.Rent((int)num2);
                    span.CopyTo(array2);
                    byte[] array3 = array;
                    span = (array = array2);
                    if (array3 != null)
                    {
                        ArrayPool<byte>.Shared.Return(array3);
                    }
                }
                int num3 = RandomAccess.ReadAtOffset(sfh, span.Slice(num), num);
                if (num3 == 0)
                {
                    break;
                }
                num += num3;
            }
            return span.Slice(0, num).ToArray();
        }
        finally
        {
            if (array != null)
            {
                ArrayPool<byte>.Shared.Return(array);
            }
        }
    }

Классная работа ученика школы информационных технологий для умственно отсталых. Зато всё большими буквами, ага.


И кстати, мой "говнокод" спокойно загружает файлы размером свыше 2ГБ, а у вашей чудесной File.ReadAllBytes слетает кабина:

Unhandled exception. System.IO.IOException: The file is too long. This operation is currently limited to supporting files less than 2 gigabytes in size.
   at System.IO.File.ReadAllBytes(String path)
   at ConsoleApp1.Program.Main(String[] args) in E:\Development\VS2022\ConsoleApp1\Program.cs:line 8

E:\Development\VS2022\ConsoleApp1\bin\Release\net8.0\ConsoleApp1.exe (process 644) exited with code -532462766.
Press any key to close this window . . .

Это просто гениально, тупо размер файла ограничили и все! И никаких проблем с преобразованием знаковых-беззнаковых, класс!


Тебя все еще удивляет, почему в std нет аналога File.ReadAllBytes? Отвечаю: потому что нафиг мне не упало в std такое счастье.