El código lee el archivo desde el desplazamiento especificado al número especificado de bytes. Cómo manejar los errores de lecturas parciales en la lectura de un archivo [cerrado] -- ampo con linux campo con unix camp codereview Relacionados El problema

The code reads the file from the specified offset to the specified number of bytes. How to handle errors of partial reads in reading a file [closed]


-2
vote

problema

Español
cerrado. Esta pregunta es off-topic . Actualmente no está aceptando respuestas.

¿Quieres mejorar esta pregunta? Actualizar la pregunta por lo que es on-topic para el intercambio de pila de revisión de código.

cerrado hace 11 meses .

Mejorar esta pregunta

Me gustaría leer un archivo de un desplazamiento específico a un cierto número de bytes en un archivo. Pasaría el nombre de archivo, la compensación, el número de bytes como un argumento. La restricción debe usar solo leer, escribir, abrir y cerrar la llamada del sistema. ¿Alguien podría decir si el código manejaría el caso de prueba de bytes & gt; buf_size y lecturas parciales? Soy principiante en Linux. Muchas gracias.

  #include<stdio.h> #include<stdlib.h> #include<unistd.h> #include<sys/types.h> #include<error.h> #include<errno.h> #include<fcntl.h> #define buf_size 512  int main(int argc, char *argv[]) {        int bytes;     int offset;     int fd;      int i = 0;      int length = 0;     ssize_t read_bytes;     char *file;     char buf[buf_size];     char *bufp;      if (argc != 4)         error(1, 0, "Too many or less than the number of arguments");     file = argv[1];     offset = atoi(argv[2]);     bytes = atoi(argv[3]);     fd = open(file, O_RDONLY);     if (fd == -1)         error(1, errno, "Error while opening the file ");     read(fd, buf, offset);     do {                     read_bytes = read(fd, buf, bytes);         if (read_bytes == -1)                 error(1, errno, "Error while reading the file ");         if (read_bytes == 0)             return 0;         for (i = 0; i < bytes; i++)                 putchar(buf[i]);         if (close(fd) == -1)                     error(1, 0, "Error while closing the file ");     } while (read_bytes != 0); } ```   
Original en ingles

I could like to read a file from a specified offset to a certain number of bytes in a file. I would pass the filename, the offset, the number of bytes as an argument. The constraint is should use only read, write, open, and close system call. Could anyone say whether the code would handle the test case of bytes > buf_size and partial reads? I am beginner in Linux. Thanks a ton.

#include<stdio.h> #include<stdlib.h> #include<unistd.h> #include<sys/types.h> #include<error.h> #include<errno.h> #include<fcntl.h> #define buf_size 512  int main(int argc, char *argv[]) {        int bytes;     int offset;     int fd;      int i = 0;      int length = 0;     ssize_t read_bytes;     char *file;     char buf[buf_size];     char *bufp;      if (argc != 4)         error(1, 0, "Too many or less than the number of arguments");     file = argv[1];     offset = atoi(argv[2]);     bytes = atoi(argv[3]);     fd = open(file, O_RDONLY);     if (fd == -1)         error(1, errno, "Error while opening the file\n");     read(fd, buf, offset);     do {                     read_bytes = read(fd, buf, bytes);         if (read_bytes == -1)                 error(1, errno, "Error while reading the file\n");         if (read_bytes == 0)             return 0;         for (i = 0; i < bytes; i++)                 putchar(buf[i]);         if (close(fd) == -1)                     error(1, 0, "Error while closing the file\n");     } while (read_bytes != 0); } ``` 
        
         
         

Lista de respuestas

2
 
vote
vote
La mejor respuesta
 

error

En este bucle, el archivo está cerrado, esto significa que en la siguiente iteración del bucle, la lectura fallará.

      do {         read_bytes = read(fd, buf, bytes);         if (read_bytes == -1)             error(1, errno, "Error while reading the file ");         if (read_bytes == 0)             return 0;         for (i = 0; i < bytes; i++)             putchar(buf[i]);         if (close(fd) == -1)             error(1, 0, "Error while closing the file ");     } while (read_bytes != 0);   

Complejidad

La función public bool CategoryMatchesRule(DiscountRule rule, int categoryId) { return rule.AllCategories || rule.CategoryId == categoryId; } 0 es demasiado complejo (hace demasiado). A medida que los programas crecen en tamaño, el uso de public bool CategoryMatchesRule(DiscountRule rule, int categoryId) { return rule.AllCategories || rule.CategoryId == categoryId; } 1 debe limitarse a las funciones de llamadas que analizan la línea de comandos, las funciones de llamadas que configuran para el procesamiento, las funciones de llamada que ejecutan la función deseada del programa y las funciones de llamada Para limpiar después de la parte principal del programa.

También hay un principio de programación llamado Principio de la responsabilidad única que se aplica aquí. El principio de la responsabilidad única dice:

que cada módulo, clase o función debe tener la responsabilidad en una sola parte de la funcionalidad proporcionada por el software, y esa responsabilidad debe ser encapsulada por completo por ese módulo, clase o función.

Hay al menos 2 funciones posibles en public bool CategoryMatchesRule(DiscountRule rule, int categoryId) { return rule.AllCategories || rule.CategoryId == categoryId; } 2 .
- analizar los argumentos de la línea de comandos
- Lea el archivo usando el desplazamiento y el tamaño

El código no es portátil

Los archivos de encabezado public bool CategoryMatchesRule(DiscountRule rule, int categoryId) { return rule.AllCategories || rule.CategoryId == categoryId; } 3 y public bool CategoryMatchesRule(DiscountRule rule, int categoryId) { return rule.AllCategories || rule.CategoryId == categoryId; } 4 no son portátiles, y cualquier código que se deriva de ellos, como la función public bool CategoryMatchesRule(DiscountRule rule, int categoryId) { return rule.AllCategories || rule.CategoryId == categoryId; } 5 no haga un puerto para Sistemas como Windows. En el caso de public bool CategoryMatchesRule(DiscountRule rule, int categoryId) { return rule.AllCategories || rule.CategoryId == categoryId; } 6 , sería mejor reportar el error a public bool CategoryMatchesRule(DiscountRule rule, int categoryId) { return rule.AllCategories || rule.CategoryId == categoryId; } 7 usando public bool CategoryMatchesRule(DiscountRule rule, int categoryId) { return rule.AllCategories || rule.CategoryId == categoryId; } 8 y como se encuentra en public bool CategoryMatchesRule(DiscountRule rule, int categoryId) { return rule.AllCategories || rule.CategoryId == categoryId; } 9 if(BrandMatchesRule(rule, brandId) && CategoryMatchesRule(rule, categoryId)) 0 OF if(BrandMatchesRule(rule, brandId) && CategoryMatchesRule(rule, categoryId)) 1 se incluye 99887776655443322 . Tenga en cuenta que si bien if(BrandMatchesRule(rule, brandId) && CategoryMatchesRule(rule, categoryId)) 3 no es portátil, 99887766555443324 es portátil ya que es parte del estándar de programación C.

Mensajes de error comprensibles

Es bastante común tener un cheque en if(BrandMatchesRule(rule, brandId) && CategoryMatchesRule(rule, categoryId)) 5 , pero el mensaje de error proporcionado generalmente proporciona la llamada correcta del programa como ejemplo. El mensaje de error if(BrandMatchesRule(rule, brandId) && CategoryMatchesRule(rule, categoryId)) 6 realmente no le dice al usuario lo suficiente, como lo que faltan los argumentos y en qué orden deben estar.

  if(BrandMatchesRule(rule, brandId) && CategoryMatchesRule(rule, categoryId)) 7  

Más fácil de usar

El programa podría ser un poco más fácil de usar si fue más flexible, en lugar de esperar desplazamiento como if(BrandMatchesRule(rule, brandId) && CategoryMatchesRule(rule, categoryId)) 8 y bytes para leer como if(BrandMatchesRule(rule, brandId) && CategoryMatchesRule(rule, categoryId)) 9 offset DiscountRule0 < / Código> Bytes a leer`.

 

Bug

In this loop the file is closed, this means that on the next iteration of the loop the read will fail.

    do {         read_bytes = read(fd, buf, bytes);         if (read_bytes == -1)             error(1, errno, "Error while reading the file\n");         if (read_bytes == 0)             return 0;         for (i = 0; i < bytes; i++)             putchar(buf[i]);         if (close(fd) == -1)             error(1, 0, "Error while closing the file\n");     } while (read_bytes != 0); 

Complexity

The function main() is too complex (does too much). As programs grow in size the use of main() should be limited to calling functions that parse the command line, calling functions that set up for processing, calling functions that execute the desired function of the program, and calling functions to clean up after the main portion of the program.

There is also a programming principle called the Single Responsibility Principle that applies here. The Single Responsibility Principle states:

that every module, class, or function should have responsibility over a single part of the functionality provided by the software, and that responsibility should be entirely encapsulated by that module, class or function.

There are at least 2 possible functions in main().
- Parse the command line arguments
- Read the file using the offset and size

The Code is Not Portable

The header files error.h and unistd.h are not portable, and any code that derives from them such as the function error() do not port to systems such as windows. In the case of error() it would be better to report the error to stderr using fprintf() and since this is in main() return 1; or if stdlib.h is included return EXIT_FAILURE;. Note that while error() is not portable, perror() is portable since it is part of the C programming standard.

Understandable Error Messages

It is quite common to have a check on argc, but the error message provided usually provides the correct calling of the program as an example. The error message Too many or less than the number of arguments really doesn't tell the user enough, such as what arguments are missing, and what order they should be in.

    if (argc != 4)     {         fprintf(stderr, "Usage: readbytes Offset Bytes to read");         return EXIT_FAILURE;    // since stdlib.h is included     } 

More User Friendly

The program could be a little more user friendly if it was more flexible, rather than expecting Offset as argv[2] and Bytes to Read as argv[3] Use -O foroffsetand -B forBytes to Read`.

 
 

Relacionados problema

9  Plataforma independiente donde la función  ( Platform independent whereis function ) 
Estoy tratando de escribir un paquete independiente de Python (& gt; = 3.6.5) que tiene un puñado de archivos de clase Java. Clase que necesitan compilarse us...

4  Huffman que codifica como Utilidad de la línea de comandos de estilo UNIX  ( Huffman encoding as unix style command line utility ) 
Después de ver a Tom Scott explicar Huffman codificando en este video youtube , quería Implementalo yo mismo. Quiero usar este proyecto para promover mi comp...

3  Aplicación singularidad e IPC unilateral en UNIX  ( Application uniqueness and unilateral ipc on unix ) 
este programa Detecta la singularidad de la aplicación, si la aplicación es una instancia única / primaria, lanza un servidor, de lo contrario, un cliente...

7  Patrón Pseudoportable C Script - Seguimiento  ( Pseudoportable c script pattern follow up ) 
Consulte la iteración inicial / anterior . He reescrito el script siguiendo la respuesta de @ 200_success . Ahora se ve así: #! /bin/bash # Create a...

1  Fortuna de UNIX V7 implementado en Java  ( Fortune of unix v7 implemented in java ) 
Estoy aprendiendo a Java recientemente, este es uno de mi primer programa escrito en este idioma. Reimplementación de una versión básica de Fortune . Esta ...

5  Portabilidad y "Rincón oscuro" Gotchas en este programa "WatchDog"  ( Portability and dark corner gotchas in this watchdog program ) 
El siguiente programa está destinado a "vigilando" un proceso secundario, y todos los subprocesos, el niño engendra . El comportamiento previsto es: Un ...

5  Programa de coincidencia y listado de PathName  ( Pathname matching and listing program ) 
Este programa Python 3 emite una lista de todos los nombres de ruta en el sistema de archivos que coincide con una lista de reglas tomadas de un archivo. Pued...

4  Find-grep-sed para la búsqueda de proyectos y reemplazar  ( Find grep sed for project wide search replace ) 
Siempre olvido cómo hacer esto de manera eficiente con el Arglista de VIM. Inspiración de dibujo en una publicación en Desbordamiento de la pila , escribí un...

1  ¿Cómo puedo optimizar aún más este script Perl para encontrar todos los archivos y directorios sin reconocimiento en UNIX?  ( How can i further optimize this perl script for finding all unowned files and di ) 
(originalmente publicado en Desbordamiento de pila ) Siguiendo mis hallazgos y sugerencias en mi otra publicación Cómo excluir una lista de rutas de dir...

3  Línea de comando FFMPEG para mostrar dos videos lado a lado  ( Ffmpeg command line for showing two videos side by side ) 
Aquí está la línea de comandos para jugar dos videos de lado a lado en sincronización en FFMPEG (FFPlay). Puede ser útil para los videos de comado, por ejempl...




© 2022 respuesta.top Reservados todos los derechos. Centro de preguntas y respuestas reservados todos los derechos