io.py 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. # Copyright (c) Alibaba, Inc. and its affiliates.
  2. # Copyright (c) OpenMMLab. All rights reserved.
  3. from io import BytesIO, StringIO
  4. from pathlib import Path
  5. from .file import File
  6. from .format import JsonHandler, YamlHandler
  7. format_handlers = {
  8. 'json': JsonHandler(),
  9. 'yaml': YamlHandler(),
  10. 'yml': YamlHandler(),
  11. }
  12. def load(file, file_format=None, **kwargs):
  13. """Load data from json/yaml/pickle files.
  14. This method provides a unified api for loading data from serialized files.
  15. Args:
  16. file (str or :obj:`Path` or file-like object): Filename or a file-like
  17. object.
  18. file_format (str, optional): If not specified, the file format will be
  19. inferred from the file extension, otherwise use the specified one.
  20. Currently supported formats include "json", "yaml/yml".
  21. Examples:
  22. >>> load('/path/of/your/file') # file is stored in disk
  23. >>> load('https://path/of/your/file') # file is stored on internet
  24. >>> load('oss://path/of/your/file') # file is stored in petrel
  25. Returns:
  26. The content from the file.
  27. """
  28. if isinstance(file, Path):
  29. file = str(file)
  30. if file_format is None and isinstance(file, str):
  31. file_format = file.split('.')[-1]
  32. if file_format not in format_handlers:
  33. raise TypeError(f'Unsupported format: {file_format}')
  34. handler = format_handlers[file_format]
  35. if isinstance(file, str):
  36. if handler.text_mode:
  37. with StringIO(File.read_text(file)) as f:
  38. obj = handler.load(f, **kwargs)
  39. else:
  40. with BytesIO(File.read(file)) as f:
  41. obj = handler.load(f, **kwargs)
  42. elif hasattr(file, 'read'):
  43. obj = handler.load(file, **kwargs)
  44. else:
  45. raise TypeError('"file" must be a filepath str or a file-object')
  46. return obj
  47. def dump(obj, file=None, file_format=None, **kwargs):
  48. """Dump data to json/yaml strings or files.
  49. This method provides a unified api for dumping data as strings or to files.
  50. Args:
  51. obj (any): The python object to be dumped.
  52. file (str or :obj:`Path` or file-like object, optional): If not
  53. specified, then the object is dumped to a str, otherwise to a file
  54. specified by the filename or file-like object.
  55. file_format (str, optional): Same as :func:`load`.
  56. Examples:
  57. >>> dump('hello world', '/path/of/your/file') # disk
  58. >>> dump('hello world', 'oss://path/of/your/file') # oss
  59. Returns:
  60. bool: True for success, False otherwise.
  61. """
  62. if isinstance(file, Path):
  63. file = str(file)
  64. if file_format is None:
  65. if isinstance(file, str):
  66. file_format = file.split('.')[-1]
  67. elif file is None:
  68. raise ValueError(
  69. 'file_format must be specified since file is None')
  70. if file_format not in format_handlers:
  71. raise TypeError(f'Unsupported format: {file_format}')
  72. handler = format_handlers[file_format]
  73. if file is None:
  74. return handler.dump_to_str(obj, **kwargs)
  75. elif isinstance(file, str):
  76. if handler.text_mode:
  77. with StringIO() as f:
  78. handler.dump(obj, f, **kwargs)
  79. File.write_text(f.getvalue(), file)
  80. else:
  81. with BytesIO() as f:
  82. handler.dump(obj, f, **kwargs)
  83. File.write(f.getvalue(), file)
  84. elif hasattr(file, 'write'):
  85. handler.dump(obj, file, **kwargs)
  86. else:
  87. raise TypeError('"file" must be a filename str or a file-object')
  88. def dumps(obj, format, **kwargs):
  89. """Dump data to json/yaml strings or files.
  90. This method provides a unified api for dumping data as strings or to files.
  91. Args:
  92. obj (any): The python object to be dumped.
  93. format (str, optional): Same as file_format :func:`load`.
  94. Examples:
  95. >>> dumps('hello world', 'json') # json
  96. >>> dumps('hello world', 'yaml') # yaml
  97. Returns:
  98. bool: True for success, False otherwise.
  99. """
  100. if format not in format_handlers:
  101. raise TypeError(f'Unsupported format: {format}')
  102. handler = format_handlers[format]
  103. return handler.dumps(obj, **kwargs)